You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

2349 lines
87 KiB

<template>
<div class="wrap index">
<div class="banner"
:style="{ backgroundImage: 'url(' + (form.carouselUrl || 'https://huoran.oss-cn-shenzhen.aliyuncs.com/20220613/png/1536269450851409920.png') + ')' }">
</div>
<div class="center-con">
<div class="center-wrap">
<breadcrumb :routes.sync="routes" />
<div class="content">
<div :class="['tool flex-between', { logView: !logView }]">
<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="action">
<p class="end-text" v-if="end">
距离{{ endList[status] }}还有
<em>{{ end }}</em>
</p>
<div class="m-l-20">
<p v-if="status"
:class="['sign-status', { signing: status == 2, signed: status == 1, playing: status == 4 }]">{{
form.competitionRegistration ? '已报名' : '未报名' }}</p>
<el-dropdown v-if="playingStages.length > 1" @command="chooseStage">
<el-button type="primary" style="background-color: #f96d6d;border: 0;">
选择竞赛<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="(item, i) in playingStages" :key="i" :command="item">进入{{ item.stageName
}}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<div v-else-if="status != 4 || (status == 4 && curStage)" class="status"
:class="{ wait: status == 0, signing: status == 2, signed: status == 1, playing: status == 4, finish: status == 3 || status == 5 }"
:title="statusList[status]" @click.stop="signup">{{ statusList[status] }}</div>
</div>
</div>
</div>
<div class="info">
<h6 class="title">{{ form.name }}</h6>
<div class="meta">最近编辑时间:{{ form.updateTime }}</div>
</div>
<div v-show="curType < 4">
<div class="l-title" id="part1"><img src="@/assets/img/label.png" alt=""> 竞赛信息</div>
<div v-if="form.description" class="texts ql-editor" v-html="form.description"></div>
<template v-if="form.competitionAnnexList">
<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="preview(item)">{{ item.fileName
}}</el-link>
<span v-else class="fileName">{{ item.fileName }}</span>
<el-link type="primary" :underline="false" @click="download(item)">下载</el-link>
</li>
</ul>
</template>
<template v-if="form.releaseType">
<div class="l-title"><img src="@/assets/img/label.png" alt=""> 赛程、规则与内容</div>
<h6 class="rule-title">共{{ form.competitionStage.length }}个竞赛阶段<template
v-if="info.teamLimit">,同一个团队每个成员只能参加一个阶段赛项</template>
</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 != 2">课程系统:{{ rule.systemName }}</p>
<p v-if="rule.onlineButton && rule.method != 2">线上地点:{{ 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 ? rule.customNumber : '不限制' }}</p>
<p>团队成绩计算方式:{{ teamCalculationMethods.find(e => e.id == rule.teamCalculationMethod) &&
teamCalculationMethods.find(e => e.id == rule.teamCalculationMethod).name }}</p>
</template>
<!-- <p v-if="rule.resultAnnouncementTime != 0">阶段比赛结束后{{ rule.resultAnnouncementTime }}小时,公布阶段比赛成绩。</p> -->
<div v-if="form.rule === 1 && i !== form.competitionStage.length - 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>
<!-- 竞赛排名 -->
<template v-if="curType == 4">
<div class="l-title"><img src="@/assets/img/label.png" alt=""> 竞赛排名</div>
<el-tabs v-model="curArch" @tab-click="getRank">
<el-tab-pane v-for="(item, index) in arches" :key="index" :label="item.stageName + '排名'"
:name="item.stageId"></el-tab-pane>
</el-tabs>
<el-table ref="table" :data="ranks" stripe max-height="440px" header-align="center">
<el-table-column type="index" width="60" label="排名" align="center"></el-table-column>
<template v-if="form.completeCompetitionSetup.competitionType">
<el-table-column prop="teamName" label="团队名称"></el-table-column>
<el-table-column prop="leaderName" label="队长"></el-table-column>
</template>
<el-table-column v-else prop="userName" label="姓名"></el-table-column>
<el-table-column prop="realSchool" label="学校"></el-table-column>
<el-table-column prop="school" label="用时">
<template slot-scope="scope">
{{ scope.row.timeSum }}min
</template>
</el-table-column>
<el-table-column prop="score" label="分数"></el-table-column>
</el-table>
</template>
<template v-if="curType == 5">
<div class="l-title m-t-20"><img src="@/assets/img/label.png" alt=""> 参赛信息</div>
<table v-if="form.completeCompetitionSetup.competitionType && info.team.captain === 0" class="table m-b-20">
<tr>
<th width="150">团队名称:</th>
<td>
<el-input :disabled="!editing" v-model="info.team.teamName"></el-input>
</td>
<th width="150">团队邀请码:</th>
<td>
<el-input :disabled="!editing" maxlength="6" v-model="info.team.invitationCode"></el-input>
</td>
</tr>
</table>
<div v-if="form.completeCompetitionSetup.competitionType && info.team.captain === 0 && status < 4"
class="m-b-20 text-center">
<el-button type="primary" @click="edit(1)">{{ editing ? '保存' : '编辑' }}</el-button>
</div>
<table class="table">
<template v-if="!form.completeCompetitionSetup.competitionType || info.team.captain">
<tr>
<th width="150">姓名:</th>
<td>{{ info.person.userName }}</td>
</tr>
<tr>
<th>学号:</th>
<td>{{ info.person.workNumber }}</td>
</tr>
</template>
<tr>
<th>学校:</th>
<td>
<div class="flex a-center">
<template v-if="schoolEdit">
<el-select class="m-r-10" v-model="curRealSchoolId" filterable>
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
<i class="el-icon-check icon" @click="saveSchoolId"></i>
</template>
<template v-else>
<span class="m-r-10">{{ info.person.realSchool }}</span>
<i class="el-icon-edit icon" @click="schoolEdit = 1"></i>
</template>
</div>
<!-- <span v-else>{{ info.person.realSchool }}</span> -->
</td>
</tr>
<template v-if="form.completeCompetitionSetup.competitionType && info.team.captain">
<tr>
<th width="150">团队名称:</th>
<td>
<span>{{ info.team.teamName }}</span>
</td>
</tr>
<tr>
<th>队长:</th>
<td>{{ info.captain.userName }}{{ info.captain.realSchool && ',' + info.captain.realSchool }}{{
info.captain.workNumber && ',' + info.captain.workNumber }}</td>
</tr>
<tr>
<th>团队成员:</th>
<td>
<el-tag v-for="(item, i) in info.teamDetail" :key="i" style="margin-right: 5px">{{ item.userName
}}</el-tag>
</td>
</tr>
<tr>
<th>团队邀请码:</th>
<td>
<span>{{ info.team.invitationCode }}</span>
</td>
</tr>
</template>
<tr>
<th width="130">指导老师:</th>
<td v-if="info.team.captain === 0 || !form.completeCompetitionSetup.competitionType">
<div v-if="status != 5" class="plus">
<i class="el-icon-circle-plus-outline icon" @click="addAdvisor"></i>
</div>
<div v-for="(item, i) in info.teamInstructors" :key="i" class="line">
<el-input placeholder="请输入姓名" v-model="item.name" clearable size="mini"
:disabled="!item.edit"></el-input>
<el-input placeholder="请输入职务" maxlength="10" v-model="item.position" clearable size="mini"
:disabled="!item.edit"></el-input>
<el-input placeholder="请输入手机号" maxlength="11" v-model="item.phone" clearable size="mini"
:disabled="!item.edit"></el-input>
<template v-if="status < 5">
<i v-if="item.edit" class="el-icon-check icon" @click="submitAdvisor(item, i)"></i>
<i v-else class="el-icon-edit icon" @click="editAdvisor(item)"></i>
<i class="el-icon-delete icon" @click="delAdvisor(item, i)"></i>
</template>
</div>
</td>
<td v-else>
<table class="table tc">
<tr>
<th width="60">姓名</th>
<th width="100">职务</th>
<th width="100">手机号</th>
</tr>
<template v-if="info.teamInstructors.length">
<tr v-for="(item, i) in info.teamInstructors" :key="i">
<td width="60">{{ item.name }}</td>
<td width="100">{{ item.position }}</td>
<td width="100">{{ item.phone }}</td>
</tr>
</template>
<tr v-else>
<td colspan="3">暂无数据</td>
</tr>
</table>
</td>
</tr>
<tr>
<th>竞赛阶段:</th>
<td>
<div v-if="showButton" class="m-b-10 text-right">
<el-button type="primary" :disabled="status > 3 || hasReport" :loading="allocating"
@click="automaticAllocationMember">{{
assignRecord.assignOrNot && status < 3 ? '取消' : '' }}自动分配阶段成员</el-button>
</div>
<table class="table tc">
<tr>
<th width="70">序号</th>
<th width="120">赛项阶段名称</th>
<template v-if="form.completeCompetitionSetup.competitionType">
<th width="110">参赛人数限制</th>
<th>
允许参赛人员
<el-tooltip v-if="stageTip" effect="dark" content="阶段参赛人员异常,请尽快按照阶段赛规则调整,否则可能影响比赛成绩!"
placement="bottom">
<i class="info el-icon-warning" style="margin-right: 10px;color: #ff1650;"></i>
</el-tooltip>
</th>
</template>
<th v-if="form.rule === 0" width="70">总分</th>
<th>竞赛成绩</th>
</tr>
<template v-if="info.stages.length">
<tr v-for="(item, i) in info.stages" :key="i">
<td>{{ i + 1 }}</td>
<td>{{ item.stageName || form.name }}</td>
<template v-if="form.completeCompetitionSetup.competitionType">
<td>{{ item.teamNumLimit ? item.customNumber : '不限制' }}</td>
<td>
<template v-if="item.participants">
<el-tag v-for="tag in item.participants" :key="tag.name" class="m-r-5 m-b-5"
:closable="info.team.captain === 0 && status < 4" @close="removePar(tag, item)">
{{ tag.name }}
</el-tag>
</template>
<span v-else class="m-r-5">无</span>
<i v-if="info.team.captain === 0 && status < 4" class="el-icon-edit icon"
@click="selectPar(item)"></i>
<el-tooltip v-if="stageTip && stageTip[i + 1]" effect="dark" :content="stageTip[i + 1]"
placement="bottom">
<el-tag type="danger" class="m-l-5">异常</el-tag>
</el-tooltip>
</td>
</template>
<!-- 积分赛才需要显示总分这个字段,直接第一行合并表格 -->
<td v-if="form.rule === 0 && !i" :rowspan="info.stages.length">{{ info.totalScore }}</td>
<td>
<!-- 成绩公布时间到了后,才显示下面的分数和查看详情按钮 -->
<template v-if="item.showDetail">
<span v-if="item.score >= 0" class="m-r-10">分数{{ item.score }}</span>
<!-- 团队赛 or (个人赛 并且 是否公布成绩详情勾选的是 并且 有reportId) -->
<el-button
v-if="form.completeCompetitionSetup.competitionType || (!form.completeCompetitionSetup.competitionType && item.resultsDetails === 0 && item.reportId)"
type="text" @click="show(item)">查看成绩详情</el-button>
</template>
</td>
</tr>
</template>
<tr v-else>
<td colspan="6">暂无数据</td>
</tr>
</table>
<!-- 团队&&队长才显示 -->
<el-alert v-if="form.completeCompetitionSetup.competitionType && info.team.captain === 0"
style="margin-top: 10px;"
:title="'注:请团长(团队创建人)设置各阶段参赛成员,只有被选择的允许参赛成员可进入对应阶段比赛' + (info.teamLimit ? ',每个团队成员只能参加一个赛项阶段' : '') + '!'"
type="warning" show-icon>
</el-alert>
</td>
</tr>
</table>
<!-- 团队&&队长才显示 -->
<template v-if="form.completeCompetitionSetup.competitionType && info.team.captain === 0">
<div class="flex a-center m-t-20 m-b-20">
<div class="l-title" style="margin: 0 20px 0 0">团队成员</div>
<el-tag v-for="(item, i) in teamErrors" :key="i" type="danger" style="margin-right: 5px">{{ item
}}</el-tag>
</div>
<div class="flex-center">
<p>队长:{{ info.captain.userName }}</p>
<el-button type="primary" @click="transfer">转让队长</el-button>
</div>
<el-alert style="margin: 10px 0;" title="请确保团队成员人数满足大赛要求,否则无法参加比赛" type="success" :closable="false">
</el-alert>
<el-table :data="info.teamDetail" stripe header-align="center">
<el-table-column prop="userName" label="成员姓名" min-width="100" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学校" min-width="100" align="center"></el-table-column>
<el-table-column prop="workNumber" label="学号" min-width="100" align="center"></el-table-column>
<el-table-column prop="createTime" label="加入时间" width="180" align="center"></el-table-column>
<el-table-column label="操作" align="center" width="160">
<template slot-scope="scope">
<el-button v-if="scope.row.captain" type="text" @click="removeLine(scope.row)">踢出团队</el-button>
</template>
</el-table-column>
</el-table>
</template>
</template>
</div>
</div>
</div>
<!-- 个人报名(有赛事邀请码的情况,没有赛事邀请码的情况不用弹框,直接报名成功) -->
<el-dialog title="报名" :visible.sync="peopleSignupVisible" :close-on-click-modal="false" width="300px">
<el-form class="dia-form">
<el-form-item label="来自学校">
<el-select v-model="peopleSignupForm.realSchoolId" filterable style="width: 100%">
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="form.completeCompetitionSetup.isNeedCode">
<el-input placeholder="请输入4位数大赛邀请码" maxlength="4"
v-model="peopleSignupForm.registrationInvitationCode"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button size="small" type="primary" @click="peopleSignupSubmit">报名</el-button>
<el-button size="small" @click="peopleSignupVisible = false">取消</el-button>
</span>
</el-dialog>
<!-- 安财赛事报名专用(个人及团队都用这个) -->
<el-dialog v-if="fromOffical" title="报名" :visible.sync="enterVisible" :close-on-click-modal="false" width="850px"
custom-class="enter-dia" @close="enterClose">
<div class="flex">
<el-form class="dia-form" label-width="90px">
<el-form-item label="姓名">
<el-input disabled v-model="userName"></el-input>
</el-form-item>
<el-form-item label="来自学校">
<el-select v-model="enterForm.realSchoolId" filterable style="width: 100%">
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
</el-form-item>
<!-- 团队报名 -->
<template v-if="form.completeCompetitionSetup.competitionType">
<p class="m-t-20 m-b-5">请选择要加入的团队</p>
<el-form-item label="团队">
<el-select class="w-100" v-model="enterForm.teamId" filterable>
<el-option v-for="(item, i) in teams" :key="i" :label="item.teamName" :value="item.teamId"></el-option>
</el-select>
</el-form-item>
<el-form-item label="团队邀请码">
<el-input placeholder="请输入团队邀请码" maxlength="6" v-model="enterForm.invitationCode"></el-input>
</el-form-item>
</template>
<el-form-item label="大赛邀请码" v-if="form.completeCompetitionSetup.isNeedCode">
<el-input placeholder="请输入大赛邀请码" maxlength="4" v-model="enterForm.registrationInvitationCode"></el-input>
</el-form-item>
<p v-if="form.completeCompetitionSetup.competitionType" class="tips">
查找不到团队?点击 <el-link :underline="false" type="primary" @click="toTeam">创建团队</el-link>
</p>
</el-form>
<div class="agree">
<div class="agreement">
<h6>参赛选手承诺书</h6>
<div class="text">
<p class="line">本人自愿参加2024年安徽省大学生金融投资创新大赛,为进一步提高廉洁自律意识,客观公正的履行职责,我以大赛参赛学生的身份和荣誉郑重作出如下承诺:</p>
<p class="line">1.尊重大赛组委会及秘书处,尊重专家和仲裁,尊重参赛单位和其他选手,客观、公正地参加比赛。</p>
<p class="line">
2.遵守道德,遵守大赛纪律,不私下接触其他参赛单位和团队成员、专家、裁判员、仲裁员。
</p>
<p class="line">
3.保证提交的所有信息、数据和材料均真实、准确、合法及有效,不侵犯任何第三方的知识产权和其他权益。参赛选手均无条件配合大赛组委会对参赛选手提供的数据、信息、材料及有关情况等进行核实。
</p>
<p class="line">4.遵守公正、公平原则,不干扰裁判员、仲裁员等工作及其他参赛单位和团队成员等比赛,影响比赛成绩。认可大赛组委会提供的基础数据。</p>
<p class="line">5.不发表、不传播没有根据并对大赛产生不利影响的言论。</p>
<p class="line">6.不隐瞒按规定应该回避的事项。</p>
<p class="line">7.对于涉嫌泄密事宜,愿接受、协助、配合相关部门的监督检查,并履行举证义务。</p>
<p class="line">8.如若发生上述问题,自愿承担相关责任。</p>
<p class="line">特此承诺!</p>
<p class="line">勾选后才可登录和注册!</p>
</div>
</div>
<el-checkbox class="m-t-15 m-l-20" v-model="agreeCheck">同意,我已阅读</el-checkbox>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button size="small" type="primary" @click="officalEnterSubmit">报名</el-button>
<el-button size="small" @click="enterVisible = false">取消</el-button>
</span>
</el-dialog>
<!-- 常规团队报名 -->
<el-dialog v-else title="报名" :visible.sync="enterVisible" :close-on-click-modal="false" width="300px"
@close="enterClose">
<el-form class="dia-form">
<el-form-item label="来自学校">
<el-select v-model="enterForm.realSchoolId" filterable style="width: 100%">
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
</el-form-item>
<el-form-item label="请选择要加入的团队">
<el-select class="w-100" v-model="enterForm.teamId" filterable>
<el-option v-for="(item, i) in teams" :key="i" :label="item.teamName" :value="item.teamId"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-input placeholder="请输入团队邀请码" maxlength="6" v-model.trim="enterForm.invitationCode"></el-input>
</el-form-item>
<el-form-item v-if="form.completeCompetitionSetup.isNeedCode">
<el-input placeholder="请输入大赛邀请码" maxlength="4" v-model.trim="enterForm.registrationInvitationCode"></el-input>
</el-form-item>
<p class="tips">
查找不到团队?点击 <el-link :underline="false" type="primary" @click="toTeam">创建团队</el-link>
</p>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button size="small" type="primary" @click="enterSubmit">报名</el-button>
<el-button size="small" @click="enterVisible = false">取消</el-button>
</span>
</el-dialog>
<el-dialog title="创建团队" :visible.sync="teamVisible" :close-on-click-modal="false" width="300px" @close="teamClose">
<el-form class="dia-form">
<el-form-item>
<el-input placeholder="请输入团队名称" maxlength="10" v-model.trim="teamForm.teamName"></el-input>
</el-form-item>
<el-form-item>
<el-input placeholder="请设置团队邀请码" maxlength="6" v-model.trim="teamForm.invitationCode"></el-input>
</el-form-item>
<el-form-item v-if="form.completeCompetitionSetup.isNeedCode">
<el-input placeholder="请输入大赛邀请码" maxlength="4" v-model.trim="teamForm.registrationInvitationCode"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button size="small" type="primary" @click="teamSubmit">创建并报名</el-button>
<el-button size="small" @click="teamVisible = false">取消</el-button>
</span>
</el-dialog>
<el-dialog title="选择参赛成员" :visible.sync="transferVisible" :close-on-click-modal="false" width="400px">
<template v-for="(item, i) in info.teamDetail">
<el-radio v-if="item.captain" :key="i" v-model="checkedPlayer" :label="item.teamId">{{ item.userName
}}</el-radio>
</template>
<span slot="footer" class="dialog-footer">
<el-button size="small" type="primary" @click="transferSubmit">确定</el-button>
<el-button size="small" @click="transferVisible = false">取消</el-button>
</span>
</el-dialog>
<el-dialog title="选择参赛成员" :visible.sync="chooseVisible" :close-on-click-modal="false" width="400px">
<el-checkbox-group v-model="checkedMembers">
<el-checkbox v-for="(item, i) in chooses" :key="i" :label="item.accountId">{{ item.userName }}</el-checkbox>
</el-checkbox-group>
<p v-if="info.teamLimit && curRow.customNumber" style="margin-top: 15px;font-size: 12px;">注:当前阶段限制{{
curRow.customNumber }}人参赛,且此竞赛每个成员只能参加一个阶段赛项。</p>
<span slot="footer" class="dialog-footer">
<el-button size="small" type="primary" @click="chooseSubmit">确定</el-button>
<el-button size="small" @click="chooseVisible = false">取消</el-button>
</span>
</el-dialog>
<el-dialog title="团队得分详情" :visible.sync="memberVisible" width="900px" :close-on-click-modal="false">
<h6 v-if="members.length" style="margin-bottom: 10px;font-size: 16px;">团队名称:{{ members[0].teamName }} 阶段名称:{{
curRow.stageName }}</h6>
<table class="table tc">
<tr>
<th width="60">序号</th>
<th width="100">姓名</th>
<th width="100">学校</th>
<th width="100">用时</th>
<th width="100">分数</th>
<th width="100">得分详情</th>
</tr>
<template v-if="members.length">
<tr v-for="(item, i) in members" :key="i">
<td>{{ i + 1 }}</td>
<td>{{ item.userName }}</td>
<td>{{ item.realSchool }}</td>
<td>{{ item.timeSum }}min</td>
<td>{{ item.score }}</td>
<td>
<!-- 成绩公布时间到了后才显示该按钮 -->
<el-button v-if="curRow.resultsDetails === 0 && item.reportId" type="text"
@click="toReport(item)">查看</el-button>
</td>
</tr>
</template>
<tr v-else>
<td colspan="6">暂无数据</td>
</tr>
</table>
<span slot="footer" class="dialog-footer">
<el-button size="small" type="primary" @click="memberVisible = false">确定</el-button>
</span>
</el-dialog>
<el-dialog :title="curStage ? curStage.stageName : ''" :visible.sync="stageVisible" :close-on-click-modal="false"
width="600px" @close="stageClose">
<template v-if="curStage && curStage.competitionStageContentSetting">
<div v-if="curStage.competitionStageContentSetting.systemLink" class="m-b-20">
<span class="fs-14">进入比赛:</span>
<el-button type="danger" style="font-size: 13px" @click="toOffline">进入{{ curStage.stageName }}</el-button>
</div>
<div v-if="curStage.competitionStageContentSetting.fileUrl" class="flex m-b-20 fs-14">
<span style="padding-top: 7px">文件下载:</span>
<div>
<div v-for="(file, i) in curStage.competitionStageContentSetting.fileList" :key="i">
<span style="margin-right: 10px;color: #606266;">{{ file.name }}</span>
<el-button type="text" style="font-size: 14px"
@click="download({ fileName: file.name, filePath: file.url })">点击下载</el-button>
</div>
</div>
</div>
<div class="flex m-b-20">
<span class="fs-14">文件上传:</span>
<el-upload class="file-upload flex-1" :disabled="uploading" :before-upload="beforeUpload"
:on-remove="handleRemove" :on-error="uploadError" :before-remove="beforeRemove" :on-preview="handlePreview"
:limit="1" action="" :on-exceed="handleExceed" :file-list="fileList" :http-request="handleRequest"
name="file">
<el-button size="small" type="primary" :loading="uploading"
:disabled="!!(fileList && fileList.length) || uploading">{{ uploading ? '正在上传' : fileList &&
fileList.length ? '已上传' : '上传文件' }}</el-button>
<div slot="tip" class="el-upload__tip relative">
<el-progress v-if="uploading" class="m-b-5" :stroke-width="3" :percentage="uploadProgress"></el-progress>
<p>请上传大小1G以内的文件支持常见文件格式</p>
<p>只允许上传一个文件如有多个文件则需打包再上传</p>
<div v-if="fileList.length" class="download" @click="downloadFile">下载</div>
</div>
</el-upload>
</div>
<div class="fs-14">说明:{{ curStage.competitionStageContentSetting.stageExplain }}</div>
</template>
<span slot="footer" class="dialog-footer">
<el-button size="small" @click="stageVisible = false">关闭</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { mapState, mapMutations } from "vuex";
import breadcrumb from '@/components/breadcrumb'
import Util from '@/libs/util'
import Setting from '@/setting'
import Const from '@/const/match'
import OSS from 'ali-oss'
import OssConfig from '@/components/upload/config.js'
import Oss from '@/components/upload/upload.js'
import _ from 'lodash'
export default {
name: 'matchdetail',
data () {
return {
routes: [],
headers: {
token: Util.local.get(Setting.tokenKey)
},
token: Util.local.get(Setting.tokenKey),
id: +this.$route.query.id,
fromOffical: !!this.$route.query.q, // 来自安财赛事
end: '',
status: '',
statusList: ["等待报名", "取消报名", "立即报名", "报名截止", "进入竞赛", "已结束"],
endList: ["报名开始", "报名截止", "报名截止", "竞赛开始", "竞赛结束", ""],
rules: Const.rules,
methods: Const.methods,
teamCalculationMethods: Const.teamCalculationMethods,
timerList: [],
form: {
name: '',
coverUrl: '',
description: '',
signUpStartTime: '',
signUpEndTime: '',
playStartTime: '',
playEndTime: '',
competitionStage: [],
completeCompetitionSetup: {},
competitionRegistration: {}
},
curType: '1',
typeList: [
{
id: '1',
name: '竞赛信息'
},
{
id: '2',
name: '竞赛进展'
},
{
id: '3',
name: '通知公告'
},
{
id: '4',
name: '竞赛排名'
},
],
progress: [],
timer: null,
notices: [],
noticeDetail: {},
curArch: '0',
arches: [],
ranks: [],
enterVisible: false,
enterForm: {
realSchoolId: '',
competitionId: this.$route.query.id,
teamId: '',
invitationCode: '',
registrationInvitationCode: '',
whetherSignUp: 1
},
schools: [],
agreeCheck: false,
curRealSchoolId: '',
schoolEdit: 0,
teamVisible: false,
teams: [],
teamNameRepeat: false,
teamForm: {
competitionId: this.$route.query.id,
registrationInvitationCode: '',
teamName: '',
invitationCode: '',
whetherSignUp: 1
},
curStage: null,
choosing: false,
originInfo: {},
info: {
isCaption: 0,
person: {},
captain: {},
team: {
captain: 1,
invitationCode: ''
},
stages: [],
teamDetail: [],
teamInstructors: []
},
originIns: {
id: '',
position: '',
name: '',
phone: '',
},
checkedPlayer: '',
transferVisible: false,
editing: false,
memberVisible: false,
members: [],
curRow: {},
chooseVisible: false,
checkedMember: '',
checkedMembers: [],
chooses: [],
lastType: 1,
playingStages: [],
peopleSignupVisible: false,
peopleSignupForm: {
realSchoolId: '',
registrationInvitationCode: ''
},
submiting: false,
stageVisible: false,
filesResult: {},
fileList: [],
curFileId: '',
client: null,
uploading: false,
uploadProgress: 0,
now: '',
allocated: 0,
teamErrors: [],
stageTip: null,
showButton: false,
hasReport: false,
assignRecord: {},
allocating: false,
};
},
computed: {
...mapState("user", [
"userId", 'account', 'logView', 'userName'
]),
},
components: {
breadcrumb
},
mounted () {
this.$once('hook:beforeDestroy', function () {
clearInterval(this.timer)
this.timerList.forEach(n => {
clearTimeout(n)
})
this.timerList = []
})
this.getData()
this.getProgress()
this.getNotice()
this.getTeam()
},
methods: {
// 获取竞赛信息
async getData () {
clearInterval(this.timer)
const { competition } = await this.$post(`${this.api.getCompetition}?competitionId=${this.id}`)
const list = competition.competitionAnnexList
// 附件
if (list) {
list.map(e => {
const { filePath } = e
e.canPreview = Util.canPreview(filePath.substr(filePath.lastIndexOf('.') + 1))
})
}
this.form = competition
const reg = competition.competitionRegistration
// 选择的赛事类型为设置完整比赛的才展示竞赛排名和参赛信息
if (competition.releaseType) {
const arches = []
// 积分赛才有总分排名
competition.rule === 0 ?
arches.push({
stageId: '0',
stageName: '总分'
}) :
(this.curArch = competition.competitionStage[0].stageId + '')
arches.push(...competition.competitionStage)
arches.map(e => e.stageId = e.stageId + '')
this.arches = arches
// 报名后才显示参赛信息
if (reg && !this.typeList.find(e => e.id == 5)) {
this.typeList.push({
id: '5',
name: '参赛信息'
})
await this.getInfo()
this.initOss()
}
if (this.token) {
this.getCurSchool()
this.getSchool()
this.intervalRank()
competition.completeCompetitionSetup.competitionType && this.getAutomaticAllocation() // 团队赛需要查询该赛事的分配状态
}
} else {
this.typeList = this.typeList.slice(0, 3)
}
this.routes = [
{
name: '全部赛事',
path: this.$store.state.match.referrer
},
{
name: competition.name
}
]
this.now = await Util.getNow()
this.handleStatus()
this.timer = setInterval(() => {
this.now = new Date(this.now.setSeconds(this.now.getSeconds() + 1))
this.handleStatus()
}, 1000)
},
// 定时处理时间及状态
handleStatus () {
const { form } = this
let total = ''
let time = ''
let status = ''
let signUpStartTime = new Date(this.core.dateCompatible(form.signUpStartTime)) // 报名开始时间
let signUpEndTime = new Date(this.core.dateCompatible(form.signUpEndTime)) // 报名结束时间
let playStartTime = new Date(this.core.dateCompatible(form.playStartTime)) // 比赛开始时间
let playEndTime = new Date(this.core.dateCompatible(form.playEndTime)) // 比赛结束时间
const { now } = this
if (now < signUpStartTime) { // 报名没开始
status = 0
total = signUpStartTime - now
} else if (now > signUpStartTime && now < signUpEndTime) { // 报名进行中
// 1已报名,2立即报名(没登录的情况下,直接显示立即报名,登录了则取报名信息,有则已报名,无则立即报名)
status = this.token ?
(form.competitionRegistration ?
1 :
2) :
2
total = signUpEndTime - now
} else if (now > signUpEndTime && now < playStartTime) { // 报名结束了,但比赛没开始
status = 3
total = playStartTime - now
} else if (now > playStartTime && now < playEndTime) { // 比赛进行中
// 如果是完整比赛
if (form.releaseType) {
// 进行中的赛事,则遍历每个阶段的开始结束时间,看阶段比赛是否开始
let curStage = null
const stages = form.competitionStage
if (stages) {
this.playingStages = []
form.competitionRegistration && stages.forEach(e => {
if (now >= new Date(e.startTime) && now <= new Date(e.endTime) && (e.method !== 2 || this.offlineCanEntry(e))) this.playingStages.push(e)
})
let endText = ''
for (const i in stages) {
const e = stages[i]
const startTime = new Date(e.startTime)
const endTime = new Date(e.endTime)
if (now < startTime) { // 阶段比赛未开始,不显示进入比赛按钮
endText = '阶段开始'
total = startTime - now
break
} else if (now >= startTime && now <= endTime) { // 阶段比赛进行中,显示进入比赛按钮
// 非线下赛事
if (e.method !== 2) {
if (form.competitionRegistration) { // 报名了才能进入比赛
this.statusList[4] = e.count ? '已提交' : '进入' + e.stageName
curStage = e
} else if (!this.token) {
this.statusList[4] = '进入' + e.stageName
curStage = e
}
} else if (this.offlineCanEntry(e) && form.competitionRegistration) { // 线下(输入了系统链接或者上传文件选择了是,才需要显示进入按钮)
// 当系统链接为空,且上传文件为否时,无需展示入口
// 当系统链接不为空,且上传文件为否时,点击入口,直接跳转到链接页面,无需弹窗
// 当上传文件为是时,点击入口需弹窗,共两种样式
this.statusList[4] = '进入' + e.stageName
curStage = e
}
endText = '阶段结束'
total = endTime - now
break
} else if (stages[i + 1] && now > endTime && now < new Date(stages[i + 1].startTime)) { // 过了该阶段的结束时间,但是没到下个阶段的开始时间,不显示进入比赛按钮
endText = '阶段开始'
total = new Date(stages[i + 1].startTime) - now
break
} else if (i === stages.length - 1) { // 当前时间在比赛开始结束时间之间,并且是最后一个阶段结束时间之后
this.$set(form, 'stageName', '')
endText = '竞赛结束'
total = playEndTime - now
break
}
}
this.endList[4] = endText
}
if (!this.choosing) this.curStage = curStage
} else { // 仅发布信息
total = playEndTime - now
}
status = 4
} else if (now > playEndTime) { // 比赛结束
status = 5
}
this.status = status
total = total / 1000
--total
if (total > 86400) { // 超过一天则显示天数
// clearInterval(this.timer)
this.end = Math.floor(total / 86400) + '天'
} else if (total > 0) { // 一天之内,显示时分秒
let hours = Math.floor(total / (60 * 60))
let minutes = Math.floor(total % (60 * 60) / 60)
let seconds = Math.floor(total % (60 * 60) % 60)
time = `${this.core.formateTime(hours)}:${this.core.formateTime(minutes)}:${this.core.formateTime(seconds)}`
if (total > 0) this.end = time
} else if (this.status === 5) { // 竞赛结束,清除定时器
clearInterval(this.timer)
}
},
// 该阶段是否符合线下能进入比赛的条件
offlineCanEntry (stage) {
return stage.method === 2 && stage.competitionStageContentSetting && !!(stage.competitionStageContentSetting.systemLink || stage.competitionStageContentSetting.whetherToUploadFiles)
},
// 获取竞赛信息
getInfo () {
this.$post(`${this.api.entryInformation}?competitionId=${this.id}`).then(async res => {
const info = res.entryInformation
// 如果是队长,并且没有指导老师,默认添加一个空的
if (info.team && !info.team.captain && !info.teamInstructors.length) info.teamInstructors.push(_.cloneDeep(this.originIns))
if (info.personalDetail) {
info.team = {}
info.teamDetail = []
} else {
info.isCaption = info.team.captain
}
const captain = info.teamDetail.find(e => !e.captain)
info.captain = captain ? captain : {}
info.person = info.personalDetail || info.teamDetail.find(e => e.accountId == info.team.accountId)
if (info.person) this.curRealSchoolId = info.person.realSchoolId
this.originInfo = _.cloneDeep(info)
// 把参赛人员的名字和accountId处理成一个数组
info.stages && info.stages.map(e => {
if (e.participantAccountIds && e.teamParticipantIds) {
const accountIds = e.participantAccountIds.split(',').map(n => +n)
const names = e.teamParticipantIds.split(',')
const participants = []
accountIds.map((n, i) => {
participants.push({
id: n,
name: names[i]
})
})
e.participants = participants
}
})
// 设置定时器,阶段比赛结束后公布成绩,到时间后调本接口
const now = await Util.getNow()
this.form.competitionStage && this.form.competitionStage.map(e => {
// 如果成绩公布时间输入的值大于0(输入的是0则直接公布;没输入值则不公布)
const time = e.resultAnnouncementTime
if (time >= 0) {
const endTime = new Date(e.endTime).getTime() + time * 3600000 // 阶段结束时间+成绩公布时间(成绩公布时间单位是小时,所以要转化为毫秒)
if (now > endTime) { // 如果到了公布时间
info.stages.find(n => n.stageId == e.stageId).showDetail = 1
} else if (endTime - now < 86400000) { // 没有到公布时间,则加定时器,到点后调用
this.timerList.push(setTimeout(this.getInfo, endTime - now))
}
}
})
this.info = info
this.schoolEdit = 0
if (this.form.completeCompetitionSetup.competitionType) {
this.getErrorInfo()
this.getTeamAssign()
}
}).catch(err => { });
},
// 获取团队异常信息
async getErrorInfo () {
const res = await this.$get(this.api.checkTeamStatus, {
competitionId: this.id,
teamId: this.info.teamId
})
this.teamErrors = res.teamTip.split(';').filter(e => e)
if (Object.keys(res.stageTip).length) {
this.stageTip = res.stageTip
} else {
this.stageTip = null
}
},
// 编辑保存
edit (showMsg) {
if (this.editing || !showMsg) {
const { teamId, teamName, invitationCode } = this.info.team
this.$post(this.api.editCompetitionTeam, {
competitionId: this.id,
teamId,
teamName,
invitationCode,
whetherSignUp: 0
}).then(res => {
this.editing = false
this.getInfo()
showMsg && Util.successMsg('保存成功')
}).catch(res => { })
} else {
this.editing = !this.editing
}
},
getProgress () { // 获取竞赛进展
this.$get(this.api.getCompetitionProgress, {
competitionId: this.id
}).then(res => {
this.progress = res.competitionProgressList.reverse()
}).catch(err => { });
},
// 公告列表
getNotice () {
this.$post(`${this.api.queryAnnouncementByCompetitionId}?pageNum=1&pageSize=1000&competitionId=${this.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 => { })
},
// 预览附件
preview (item) {
const { filePath } = item
const suffix = filePath.substr(filePath.lastIndexOf('.') + 1)
window.open((Util.isDoc(suffix) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + item.filePath)
},
// 下载附件
download (item) {
Util.downloadFile(item.fileName, item.filePath)
},
// tab切换 前三个滚动,后两个切换
typeChange () {
const type = +this.curType
// 如果上个选中的是参赛信息,则检查修改数据后有没保存(团队名称、邀请码、指导老师)
if (this.lastType == 5) {
const { team, teamInstructors } = this.info
const { originInfo } = this
let notSave = 0
// 如果团队名称或者邀请码有修改
if (team.teamName !== originInfo.team.teamName || team.invitationCode !== originInfo.team.invitationCode) {
notSave = 1
} else if (JSON.stringify(teamInstructors) !== JSON.stringify(originInfo.teamInstructors)) {
notSave = 2
}
// debugger
if (notSave) {
this.$confirm('所填写内容暂未保存,是否保存?', "提示", {
type: "warning",
closeOnClickModal: false
}).then(() => {
// 保存团队名称和邀请码
if (notSave === 1) {
this.edit()
} else { // 保存指导老师
teamInstructors.map(e => {
e.name && this.$post(this.api.addAnAdvisor, {
name: e.name,
competitionId: this.id,
id: e.id,
teamId: this.form.competitionRegistration ? this.form.competitionRegistration.teamId : '',
phone: e.phone,
position: e.position,
}).then(res => { }).catch(res => { })
})
}
}).catch(() => { })
} else {
type < 4 && document.querySelector(`#part${type}`).scrollIntoView()
}
} else {
type == 5 && this.getInfo()
type < 4 && document.querySelector(`#part${type}`).scrollIntoView()
}
this.editing = false
this.lastType = type
},
// 跳转公告详情
toNotice (item) {
this.$router.push(`noticeDetail?id=${item.id}&matchId=${this.id}&name=${this.form.name}&end=${this.end}&status=${this.status}`)
},
// 获取排名
getRank () {
const cur = +this.curArch
const data = {
pageNum: 1,
pageSize: 20,
competitionId: this.id,
isOverallRanking: cur ? 0 : 1
}
data.stageIds = cur ? cur : ''
this.token && this.$post(this.api.frontOfficeCompetitionRanking, data).then(({ list }) => {
this.ranks = list
}).catch(res => { })
},
// 定时调获取排名接口
intervalRank () {
this.getRank()
},
// 删除指导老师
delAdvisor (row, i) {
if (row.id) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.deleteAnAdvisor}?id=${row.id}`).then(res => {
Util.successMsg('删除成功')
this.info.teamInstructors.splice(i, 1)
this.originInfo.teamInstructors = _.cloneDeep(this.info.teamInstructors)
}).catch(res => { })
}).catch(() => { })
} else {
this.info.teamInstructors.splice(i, 1)
this.originInfo.teamInstructors = _.cloneDeep(this.info.teamInstructors)
}
},
// 添加指导老师
addAdvisor () {
if (this.info.teamInstructors.length > 4) return Util.errorMsg('指导老师仅限添加5个!')
const line = _.cloneDeep(this.originIns)
line.edit = 1
this.info.teamInstructors.push(line)
},
// 编辑导老师
editAdvisor (row) {
this.$set(row, 'edit', 1)
},
// 提交指导老师
submitAdvisor (row, i) {
if (!row.name) return Util.errorMsg('请输入姓名')
const { phone } = row
if (phone && !/^1[3456789]\d{9}$/.test(phone)) return Util.errorMsg('请输入正确手机号格式')
this.$post(this.api.addAnAdvisor, {
name: row.name,
competitionId: this.id,
id: row.id,
teamId: this.form.competitionRegistration ? this.form.competitionRegistration.teamId : '',
phone: row.phone,
position: row.position,
}).then(({ id }) => {
Util.successMsg((row.id ? '修改' : '新增') + '成功')
if (!row.id) {
this.info.teamInstructors[i].id = id
}
this.info.teamInstructors[i].edit = 0
this.originInfo.teamInstructors = _.cloneDeep(this.info.teamInstructors)
}).catch(res => { })
},
// 显示转让队长
async transfer () {
// 取每个阶段的开始结束时间,有任何阶段开始了都不能转让队长和踢出队员
const now = await Util.getNow()
let start = 0
for (const e of this.form.competitionStage) {
if (now >= new Date(e.startTime) && now <= new Date(e.endTime)) {
Util.errorMsg('比赛已经开始,无法转让队长!')
start = 1
break
}
}
if (!start) this.transferVisible = true
},
// 转让队长提交
transferSubmit () {
if (!this.checkedPlayer) return Util.errorMsg('请选择成员')
this.$post(this.api.captainOfTransfer, {
captainId: this.info.captain.teamId,
playerId: this.checkedPlayer
}).then(res => {
this.checkedPlayer = ''
Util.successMsg('转让成功')
this.transferVisible = false
this.getInfo()
}).catch(res => { })
},
// 踢出团队
async removeLine (row) {
// 取每个阶段的开始结束时间,有任何阶段开始了都不能转让队长和踢出队员
const now = await Util.getNow()
let start = 0
for (const e of this.form.competitionStage) {
if (now >= new Date(e.startTime) && now <= new Date(e.endTime)) {
Util.errorMsg('比赛已经开始,无法踢出成员!')
start = 1
break
}
}
if (!start) {
let include
for (const e of this.info.stages) {
if (e.participantAccountIds) {
const ids = e.participantAccountIds.split(',').map(n => +n)
if (ids.includes(row.accountId)) {
include = e.stageName
break
}
}
}
this.$confirm(include ? `该成员已被指定参加${include},踢出后需重新指定成员参加,是否确认踢出团队?` : '确定要踢出该成员吗?', '提示', {
type: 'warning',
closeOnClickModal: false
}).then(() => {
this.$post(`${this.api.removeTheLine}?teamId=${this.info.teamId}&competitionId=${this.id}&accountId=${row.accountId}`).then(res => {
Util.successMsg('移除成功')
this.getInfo()
}).catch(res => { })
}).catch(() => { })
}
},
// 获取是否已分配
async getAutomaticAllocation () {
const res = await this.$post(`${this.api.viewEventAllocationInformation}?competitionId=${this.id}`)
this.allocated = res.data && res.data.assignOrNot
},
// 获取团队分配按钮展示与否
async getTeamAssign () {
const param = `?competitionId=${this.id}&teamId=${this.info.teamId}`
const res = await this.$post(this.api.teamAssignmentButtonDisplay + param)
this.showButton = res.showButton // 自动分配按钮是否展示
this.assignRecord = res.teamRecord || {} // 展示成自动分配 or 取消分配
// 查询团队是否存在实验报告
const res1 = await this.$post(this.api.whetherTheTeamHasReport + param)
this.hasReport = res1.hasReport
this.allocating = false
},
// 移除参赛人员
async removePar (e, stage) {
const item = this.form.competitionStage.find(e => e.stageId == stage.stageId)
if (item) {
// 该阶段已经开始比赛则不能修改
const now = await Util.getNow()
if (now >= new Date(item.startTime) && now <= new Date(item.endTime)) {
return Util.errorMsg('该阶段比赛已经开始,无法修改允许参赛人员!')
} else {
this.$confirm('确定要移除该成员吗?', '提示', {
type: 'warning'
}).then(() => {
this.$post(this.api.cancelParticipant, {
accountId: e.id,
competitionId: this.id,
stageId: stage.stageId,
teamId: this.info.teamId
}).then(res => {
Util.successMsg('移除成功')
this.getInfo()
}).catch(res => { })
}).catch(() => { })
}
}
},
// 选择参赛人员
async selectPar (row) {
const item = this.form.competitionStage.find(e => e.stageId == row.stageId)
if (item) {
// 该阶段已经开始比赛则不能修改
const now = await Util.getNow()
if (now >= new Date(item.startTime) && now <= new Date(item.endTime)) {
return Util.errorMsg('该阶段比赛已经开始,无法修改允许参赛人员!')
} else {
const { teamLimit, stages, teamDetail } = this.info
// teamLimit=true,则每个成员只能参加一个阶段的比赛,要获取stages里返回的所有participantAccountIds(参赛人员的accountId),然后不显示这些参赛人员
if (teamLimit) {
const chooses = []
let ids = []
// 获取已经允许参赛的人员accountId
stages.map(e => {
const id = e.participantAccountIds
if (e.stageId != row.stageId && id) ids.push(...id.split(',').map(n => +n))
})
ids = [...new Set(ids)]
teamDetail.map(e => {
ids.includes(e.accountId) || chooses.push(e) // 没有参赛的人员则显示出来
})
this.chooses = chooses
} else {
this.chooses = this.info.teamDetail
}
this.curRow = row
this.checkedMembers = row.participantAccountIds ? row.participantAccountIds.split(',').map(e => +e) : [] // 选中了的人员要回显
this.chooseVisible = true
}
}
},
// 选择参赛人员提交
chooseSubmit () {
const accountIds = this.checkedMembers
if (!accountIds.length) return Util.errorMsg('请选择参赛成员!')
const { customNumber, teamNumLimit } = this.curRow // 参赛人数限制
if (teamNumLimit && accountIds.length > customNumber) return Util.errorMsg(`请选择${this.curRow.customNumber}个以下参赛成员!`) // 选择的参赛人员个数不能大于参赛人数限制
this.$post(this.api.stageSelectParticipants, {
accountIds,
competitionId: this.id,
stageId: this.curRow.stageId,
teamId: this.info.teamId,
platformId: 1
}).then(res => {
this.checkedMembers = []
Util.successMsg('修改成功')
this.getInfo()
this.chooseVisible = false
}).catch(res => { })
},
// 查看成绩详情
show (row) {
this.curRow = row
// 团队展示弹框,个人跳转实验报告
if (this.form.completeCompetitionSetup.competitionType) { // 团队比赛则展示团队成员成绩详情
this.memberVisible = true
const teamId = this.form.competitionRegistration.teamId
if (teamId) {
this.$post(this.api.stageTeamScoreDetails, {
pageNum: 1,
pageSize: 1000,
competitionId: this.id,
stageId: row.stageId,
teamId
}).then(({ page }) => {
this.members = page.records
}).catch(res => { })
} else {
this.members = []
}
} else if (row.reportId) { // 个人比赛,并且有reportId,则进入实验报告
this.toReport(row)
}
},
// 跳转实验报告
toReport (row) {
this.$store.commit('project/setReferrer', this.$route.fullPath)
this.$router.push(`/record/${this.curRow.method === 1 ? 'theoryReport' : 'trialReport'}?reportId=${row.reportId}&matchId=${this.id}&matchName=${this.form.name}`)
},
// 个人报名提交
async peopleSignupSubmit () {
await this.$post(this.api.addCompetitionRegistration, {
competitionId: this.id,
...this.peopleSignupForm
})
this.peopleSignupVisible = false
this.getData()
this.$message.success('报名成功')
},
// 获取当前学校
async getCurSchool () {
const res = await this.$post(this.api.getSchoolIdByToken)
if (!this.curRealSchoolId) this.curRealSchoolId = res.schoolId
},
// 获取学校
async getSchool () {
const res = await this.$post(this.api.customerSettingsList, {
pageNum: 1,
pageSize: 10000,
})
this.schools = res.page.records
},
// 保存学校
async saveSchoolId () {
if (!this.curRealSchoolId) return Util.errorMsg('请选择学校')
await this.$post(this.api.updateRealSchoolId, {
competitionId: this.id,
realSchoolId: this.curRealSchoolId,
teamId: this.form.completeCompetitionSetup.competitionType ? this.info.teamId : '',
})
await this.getInfo()
Util.successMsg('保存成功')
},
// 团队报名提交
async enterSubmit () {
if (this.fromOffical && !this.agreeCheck) return Util.errorMsg('请勾选同意,才可继续报名!')
const form = this.enterForm
if (!form.realSchoolId) return Util.errorMsg('请选择来自学校')
if (!form.teamId) return Util.errorMsg('请选择团队')
if (!form.invitationCode) return Util.errorMsg('请输入团队邀请码')
if (this.form.completeCompetitionSetup.isNeedCode && !form.registrationInvitationCode) return Util.errorMsg('请输入大赛邀请码')
await this.$post(this.api.joinCompetitionTeam, form)
this.status = 1
this.enterVisible = false
this.getData()
Util.successMsg('报名成功!')
},
// 安财赛事报名提交
async officalEnterSubmit () {
if (this.submiting) return false
if (!this.agreeCheck) return Util.errorMsg('请勾选同意,才可继续报名!')
const form = this.enterForm
const isTeam = this.form.completeCompetitionSetup.competitionType // 团队赛
if (!form.realSchoolId) return Util.errorMsg('请选择来自学校')
if (isTeam) {
if (!form.teamId) return Util.errorMsg('请选择团队')
if (!form.invitationCode) return Util.errorMsg('请输入团队邀请码')
}
if (this.form.completeCompetitionSetup.isNeedCode && !form.registrationInvitationCode) return Util.errorMsg('请输入大赛邀请码')
this.submiting = true
await this.$post(this.api[isTeam ? 'joinCompetitionTeam' : 'addCompetitionRegistration'], form)
this.status = 1
this.enterVisible = false
this.getData()
Util.successMsg('报名成功!')
this.submiting = false
},
// 团队关闭
enterClose () {
this.enterForm = {
realSchoolId: '',
competitionId: this.id,
teamId: '',
registrationInvitationCode: '',
invitationCode: '',
whetherSignUp: 1
}
},
// 创建团队
toTeam () {
if (this.fromOffical && !this.agreeCheck) return Util.errorMsg('请勾选同意,才可创建团队!')
if (!this.enterForm.realSchoolId) return Util.errorMsg('请选择来自学校')
this.teamVisible = true
},
// 获取团队列表
getTeam () {
this.$get(this.api.searchTeam, {
teamName: '',
competitionId: this.id
}).then(({ teamList }) => {
this.teams = teamList
}).catch(res => { })
},
// 团队提交
async teamSubmit () {
const form = this.teamForm
if (!form.teamName) return Util.errorMsg('请输入团队名称')
if (this.teamNameRepeat) return Util.errorMsg('团队名称重复,请重新输入')
if (form.invitationCode.length !== 6) return Util.errorMsg('请输入6位数团队邀请码')
if (this.form.completeCompetitionSetup.isNeedCode && !form.registrationInvitationCode) return Util.errorMsg('请输入大赛邀请码')
form.realSchoolId = this.enterForm.realSchoolId
await this.$post(this.api.addCompetitionTeam, form)
this.teamVisible = false
this.enterVisible = false
await this.getData()
await this.getInfo()
Util.successMsg('报名成功!')
this.afterCreateTeam()
},
// 队长创建团队后弹框
afterCreateTeam () {
// 赛事自动分配状态为开启,则直接提示;否则弹框询问是否要启用团队自动分配
if (this.allocated) {
Util.successMsg('团队创建成功,系统将在报名结束后自动帮您分配阶段参赛成员,您也可以到参数信息进行指定')
} else {
// 未分配
this.$confirm('<p style="color: #007EFF;">报名成功!</p>您是否要启用自动分配阶段参赛人员功能?启用后,报名截止时系统将清空已有分配,并为团队所有成员重新自动分配。', '提示', {
cancelButtonText: '否',
confirmButtonText: '是',
type: 'success',
closeOnClickModal: false,
dangerouslyUseHTMLString: true,
}).then(() => {
this.automaticAllocation(1)
}).catch(() => { })
}
},
// 团队创建成功后分配
async automaticAllocation (state) {
await this.$post(this.api.competitionTeamAutomaticAllocationRecordSave, {
assignOrNot: state,
competitionId: this.id,
teamId: this.info.teamId
})
},
// 自动分配
automaticAllocationMember () {
const whether = this.assignRecord.assignOrNot && this.status < 3
const tips = this.status < 3 ?
whether ?
'您是否要取消自动分配阶段参赛人员?<p style="margin-top: 5px;font-size: 13px;color: #f00;">取消后,报名截止时将不再自动分配。</p>' :
'您是否要启用自动分配阶段参赛人员功能?<p style="margin-top: 5px;font-size: 13px;color: #f00;">启用后,报名截止时系统将清空已有分配,并为团队所有成员重新自动分配。</p>'
: '您是否要立即为团队所有成员自动分配阶段参赛人员?<p style="margin-top: 5px;font-size: 13px;color: #f00;">此操作将清除现有分配并为团队所有成员重新分配</p>'
this.$confirm(tips, '提示', {
cancelButtonText: '',
confirmButtonText: '',
type: 'success',
closeOnClickModal: false,
dangerouslyUseHTMLString: true,
}).then(async () => {
this.allocating = true
// 报名结束之前则调修改接口,否则调自动分配接口
if (this.status < 3) {
await this.$post(this.api.competitionTeamAutomaticAllocationRecordSave, {
id: this.assignRecord.id,
assignOrNot: whether ? 0 : 1,
competitionId: this.id,
teamId: this.info.teamId
})
} else {
await this.$post(`${this.api.assignedPlayer}?competitionId=${this.id}&teamId=${this.info.teamId} `)
}
this.getData()
this.getInfo()
Util.successMsg(`${whether ? '取消' : ''} 自动分配成功!`)
}).catch(() => { })
},
// 团队关闭
teamClose () {
this.teamForm = {
competitionId: this.id,
teamName: '',
invitationCode: '',
registrationInvitationCode: '',
whetherSignUp: 1
}
},
async initOss () {
const o = await OssConfig()
this.client = new OSS(o.config)
},
// 附件上传前
beforeUpload (file) {
const oversize = file.size / 1024 / 1024 < 1000
if (!oversize) Util.warningMsg('请上传小于1GB的附件!')
if (oversize) {
return true
} else {
return false
}
},
// 自定义进度条
handleProgress (progress) {
this.uploadProgress = Number((progress * 100).toFixed(2))
},
// 自定义上传
async handleRequest ({ file }) {
try {
this.fileList = []
this.uploadProgress = 0
this.uploading = true
// 先传到阿里云oss,再把url传给后端
const { name } = await this.client.multipartUpload(Date.now() + '.' + Util.getFileExt(file.name), file, {
progress: this.handleProgress
});
this.uploading = false
const url = 'https://huoran.oss-cn-shenzhen.aliyuncs.com/' + name
this.fileList = [{
name: file.name,
url
}]
// 把上传成功后的url存进文件表
const res = await this.$post(this.api.cCompetitionStageFileSave, {
competitionId: this.id,
fileFormat: Util.getFileExt(file.name),
fileName: file.name,
filePath: url,
fileSize: file.size,
stageId: this.curStage.stageId,
teamId: this.form.competitionRegistration.teamId
})
this.curFileId = res.message
Util.successMsg(`上传成功!`);
} catch (error) { }
},
downloadFile () {
const { name, url } = this.fileList[0]
Util.downloadFile(name, url)
},
handlePreview (file) {
window.open((Util.isDoc(Util.getFileExt(file.name)) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + file.url)
},
uploadError (err, file, fileList) {
this.$message({
message: "上传出错,请重试!",
type: "error",
center: true
})
},
beforeRemove (file, fileList) {
return this.$confirm(`确定移除 ${file.name}`);
},
handleExceed (files, fileList) {
Util.warningMsg(`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`);
},
// 删除文件表里的文件
handleRemove (file) {
Oss.del(file.url)
this.fileList = []
this.curFileId && this.$post(this.api.cCompetitionStageFileDel, [this.curFileId]).then(res => {
this.curFileId = ''
}).catch(res => { })
},
// 阶段弹框关闭回调
stageClose () {
this.choosing = false
this.fileList = []
this.getData()
},
// 选择要进入的阶段
chooseStage (e) {
this.choosing = true
this.curStage = e
this.signup()
},
// 判断是否能进赛事
getAllow () {
// 是否允许参加赛事(淘汰赛制)
if (this.form.rule === 1) {
this.$post(this.api.allowedParticipateCompetition, {
competitionId: this.id,
number: this.curStage.number,
stageId: this.curStage.stageId,
teamId: this.form.competitionRegistration.teamId,
}).then(res => {
this.toSub()
}).catch(res => { })
} else {
this.toSub()
}
},
// 立即报名
signup () {
const { status, form } = this
// 如果登录了
if (Util.local.get(Setting.tokenKey)) {
const { competitionType } = form.completeCompetitionSetup
if (status == 4) { // 进入比赛
// 线下(规则见handleStatus方法)
if (this.curStage.method == 2) {
// 直接打开系统链接
if (!this.curStage.competitionStageContentSetting.whetherToUploadFiles) {
window.open(this.curStage.competitionStageContentSetting.systemLink)
} else { // 显示上传文件弹框
this.stageVisible = true
// 文件路径名称处理
if (this.curStage.competitionStageContentSetting && this.curStage.competitionStageContentSetting.fileUrl) {
const urls = this.curStage.competitionStageContentSetting.fileUrl.split('|')
const names = this.curStage.competitionStageContentSetting.fileName.split('|')
this.curStage.competitionStageContentSetting.fileList = []
urls.map((n, i) => {
this.curStage.competitionStageContentSetting.fileList.push({
name: names[i],
url: n
})
})
}
const file = this.curStage.competitionStageFile
if (file) {
this.curFileId = file.id
this.fileList = [{
name: file.fileName,
url: file.filePath,
}]
}
}
} else {
// 参加过比赛不让参加
if (this.curStage && this.curStage.count) return Util.errorMsg('您已经参加过该阶段竞赛!')
if (form.competitionRegistration.isDisable === 1) return Util.errorMsg('当前用户已被禁赛,如有疑问,请联系平台管理员。') // 被禁用的用户不能进入大赛
// 团队赛,则判断是否为参赛人员
if (competitionType) {
this.$post(this.api.isParticipant, {
competitionId: this.id,
stageId: this.curStage.stageId,
teamId: form.competitionRegistration.teamId,
}).then(res => {
this.getAllow()
}).catch(res => { })
} else {
this.getAllow()
}
}
} else if (status == 2) { // 报名
// 团队赛报名(来自安财的个人团队报名都要弹框)
if (competitionType || this.fromOffical) {
this.enterVisible = true
this.agreeCheck = false
this.enterForm.realSchoolId = ''
} else { // 个人赛报名
this.peopleSignupForm = {
realSchoolId: '',
registrationInvitationCode: '',
}
this.peopleSignupVisible = true
}
} else if (status == 1) {
// 已报名,点击取消报名
this.$confirm('是否要取消报名?', '提示', {
type: 'success',
closeOnClickModal: false
}).then(() => {
this.$post(`${this.api.cancelRegistration}?competitionId=${this.id}`).then(res => {
this.status = 2
this.$message.success('取消报名成功')
this.getData()
}).catch(res => { })
}).catch(() => { })
}
} else { // 如果没登录,提示去登录
this.$confirm('请先登录,是否直接前往登录?', "提示", {
type: 'success',
closeOnClickModal: false
}).then(() => {
localStorage.setItem('toMatch', this.id)
this.$router.push('/login')
}).catch(() => { })
}
},
// 线下比赛方式点击进入跳转<比赛地点>
toOffline () {
window.open(this.curStage.competitionStageContentSetting.systemLink)
},
// 进入python系统
toPython () {
const form = this.curStage
let token = Util.local.get(Setting.tokenKey);
Util.cookies.set('assessmentId', '', -1)
Util.cookies.set('startTime', '', -1)
Util.cookies.set('stopTime', '', -1)
Util.cookies.set('projectId', form.projectId)
Util.cookies.set('token', token)
Util.cookies.set('courseId', form.cid)
Util.cookies.set('curriculumName', encodeURIComponent(form.systemName))
Util.cookies.set('systemId', form.systemId)
Util.cookies.set('isSubmit', '', -1)
Util.cookies.set('className', '', -1)
Util.cookies.set('competitionId', this.form.id)
Util.cookies.set('stageId', form.stageId)
Util.cookies.set('teamId', this.form.competitionRegistration.teamId)
Util.cookies.set('stopTime', form.endTime)
Util.cookies.set('resultsDetails', form.resultsDetails)
Util.cookies.set('resultAnnouncementTime', isNaN(form.resultAnnouncementTime) ? '' : form.resultAnnouncementTime)
Util.cookies.set('mallId', form.mallId)
Util.cookies.set('fromManager', '', -1)
Util.cookies.set('language', '', -1)
// 8个python子系统都跳这个地址,子系统会通过cookie里的systemId识别展示哪套系统
location.href = process.env.NODE_ENV === 'development' ?
`http://${location.hostname}:8085/#/` :
Setting.isPro ?
`https://${location.hostname}/pyTrials` :
`${location.origin}/pyTrials`
},
// 进入子系统
toSub () {
const { form } = this
let { systemId, systemName, projectId, cid, stageId, startTime, endTime, mallId, resultAnnouncementTime, method } = this.curStage
const competitionId = form.id
const teamId = form.competitionRegistration.teamId || ''
cid = cid || ''
mallId = mallId || ''
// 理论考试
if (method === 1) {
window.open(this.$router.resolve(`/theoryExam?competitionId=${form.id}&stageId=${stageId}&teamId=${teamId}`).href)
} else {
let token = Util.local.get(Setting.tokenKey);
if (systemId == 11) {
// 银行系统
location.href = `${Setting.systemPath}/#/index/list?curriculumName=${this.curriculumName}&token=${token}&cid=${cid}&systemId=${systemId}&projectId=${projectId}&competitionId=${competitionId}&stageId=${stageId}&teamId=${teamId}&assessmentId=&classId=&stopTime=&test=true`
} else if (systemId == 12) {
// 众筹系统
window.open(`http://${Setting.zcPath}?systemId=${systemId}&courseId=${cid}&projectId=${projectId}&token=${token}&userId=${this.userId}&classId=1&competitionId=${competitionId}&stageId=${stageId}&teamId=${teamId}&startTime=${startTime}&endTime=${endTime}&mallId=${mallId}${Setting.isTest ? '&beta=1' : ''}`);
} else if (systemId == 19) {
// 沙盘
location.href = `${Setting.sandPath}/#/?curriculumName=${systemName}&token=${token}&cid=${cid}&mallId=${mallId}&systemId=${systemId}&projectId=${projectId}&assessmentId=&classId=&startTime=&stopTime=${endTime}&competitionId=${competitionId}&stageId=${stageId}&teamId=${teamId}&resultAnnouncementTime=${isNaN(resultAnnouncementTime) ? '' : resultAnnouncementTime}&userId=${this.userId}&account=${this.account}&referrer=${encodeURIComponent(location.href)}`
} else {
// python系统
this.toPython(this.curProject)
}
}
}
}
};
</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;
}
.l-title {
font-size: 18px;
}
.main .center-con {
background: url(../../../assets/img/match-bg1.png) (0px 95px) / auto auto no-repeat,
url(../../../assets/img/match-bg2.png) (98% 300px) / auto auto no-repeat;
}
.main .center-wrap {
margin-top: 30px;
}
.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;
}
}
/deep/.el-tabs__item {
box-shadow: none !important;
}
.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;
}
.tool {
z-index: 100;
position: sticky;
top: 64px;
margin-bottom: 20px;
background-color: #fff;
&.logView {
z-index: 0;
}
}
.info .meta {
padding: 16px 0;
font-size: 12px;
color: #999;
text-align: center;
}
.action {
display: inline-flex;
align-items: center;
}
.sign-status {
margin-bottom: 10px;
text-align: center;
font-size: 14px;
color: $main-color;
&.signing {
color: $main-color;
}
&.signed {
color: #52c41a;
}
&.playing {
color: #f96d6d;
}
&:last-child {
margin-bottom: 0;
}
}
.status {
max-width: 120px;
padding: 0 16px;
line-height: 34px;
font-size: 14px;
color: #fff;
background-color: #52c41a;
border-radius: 4px;
cursor: pointer;
@include ellipsis();
&.wait {
background-color: #faad14;
}
&.signing {
background-color: $main-color;
}
&.signed {
background-color: #52c41a;
}
&.playing {
background-color: #f96d6d;
}
&.finish {
background-color: #ccc;
}
}
.end-text {
font-size: 12px;
color: #666;
em {
font-style: normal;
color: #f00;
}
}
.texts {
margin: 20px 0 50px;
font-size: 14px;
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 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: -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;
}
}
}
}
.files {
margin-bottom: 30px;
li {
display: flex;
align-items: center;
margin: 10px 0;
}
.fileName {
margin-right: 10px;
font-size: 12px;
}
}
.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;
}
}
.table {
width: 100%;
border-collapse: collapse;
th,
td {
padding: 12px;
border: 1px solid #ebeef5;
}
&.tc {
text-align: center;
}
th {
text-align: center;
background-color: #f8faff;
}
.icon {
margin-right: 10px;
font-size: 16px;
color: #7a7a7a;
cursor: pointer;
&:hover {
color: #007eff;
}
}
.plus {
margin-bottom: 10px;
text-align: right;
}
.line {
display: flex;
align-items: center;
margin-bottom: 10px;
.el-input {
margin-right: 15px;
}
}
}
.flex-center {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
/deep/.dia-form {
.w-100 {
width: 100%;
}
.tips {
display: flex;
justify-content: center;
align-items: center;
}
}
/deep/.file-upload {
.el-upload__tip {
color: #727272;
}
.el-progress {
white-space: nowrap;
}
.download {
position: absolute;
bottom: -25px;
right: 0;
font-size: 12px;
color: #007eff;
cursor: pointer;
}
.el-upload-list__item {
width: 70%;
&:first-child {
margin-top: 5px;
}
}
}
/deep/.enter-dia {
.agree {
width: 500px;
margin-left: 20px;
}
.agreement {
max-height: 300px;
padding: 10px 20px;
box-shadow: 0 0 7px rgba(235, 235, 235, .8);
overflow: auto;
h6 {
font-size: 20px;
font-weight: 600;
text-align: center;
}
.text {
line-height: 1.6;
}
.line {
margin-top: 7px;
}
}
}
</style>