123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- <template>
- <custom-layout class="main">
- <el-col :span="24" class="one" v-loading="loading">
- <div class="w_1300">
- <div class="info_1">
- <h3 class="name">{{ info.name || '暂无' }}</h3>
- <p class="brief">{{ info.industry || '暂无' }}</p>
- <p class="money" v-if="info.money">{{ info.money || '暂无' }}</p>
- <p class="type" v-if="info.match_type">{{ getDict(info.match_type, 'type') || '暂无' }}</p>
- <div class="time">
- <el-image class="image" :src="time" fit="fill"></el-image>
- <span>{{ info.start_time || '暂无' }} ~ {{ info.end_time || '暂无' }}</span>
- </div>
- <div class="button" @click="toSign">活动报名</div>
- </div>
- <div class="info_2">
- <div class="title">活动介绍</div>
- <div class="content">
- <!-- 正文 -->
- <div class="content_1">
- <div v-if="info.brief" v-html="info.brief"></div>
- <div v-else>暂无简介</div>
- </div>
- <!-- 封面 -->
- <div class="image">
- <el-image class="images" :src="getUrl(info.file, 'array')" fit="fill"></el-image>
- </div>
- </div>
- </div>
- <div class="info_3">
- <div class="title">活动说明</div>
- <div class="content">
- <div class="thr_cont" v-if="info.rules && info.rules.rules1">
- <div class="thr_1">大赛背景</div>
- <div class="thr_2">
- <div v-html="info.rules.rules1"></div>
- </div>
- </div>
- <div class="thr_cont" v-if="info.rules && info.rules.rules2">
- <div class="thr_1">大赛主题和目标</div>
- <div class="thr_2">
- <div v-html="info.rules.rules2"></div>
- </div>
- </div>
- <div class="thr_cont" v-if="info.rules && info.rules.rules3">
- <div class="thr_1">大赛基本情况介绍</div>
- <div class="thr_2">
- <div v-html="info.rules.rules3"></div>
- </div>
- </div>
- <div class="thr_cont" v-if="info.rules && info.rules.rules4">
- <div class="thr_1">赛题任务</div>
- <div class="thr_2">
- <div v-html="info.rules.rules4"></div>
- </div>
- </div>
- <div class="thr_cont" v-if="info.rules && info.rules.rules5">
- <div class="thr_1">赛程安排</div>
- <div class="thr_2">
- <div v-html="info.rules.rules5"></div>
- </div>
- </div>
- <div class="thr_cont" v-if="info.rules && info.rules.rules6">
- <div class="thr_1">赛制阶段</div>
- <div class="thr_2">
- <div v-html="info.rules.rules6"></div>
- </div>
- </div>
- <div class="thr_cont" v-if="info.rules && info.rules.rules7">
- <div class="thr_1">参赛资格</div>
- <div class="thr_2">
- <div v-html="info.rules.rules7"></div>
- </div>
- </div>
- <div class="thr_cont" v-if="info.rules && info.rules.rules8">
- <div class="thr_1">参赛报名</div>
- <div class="thr_2">
- <div v-html="info.rules.rules8"></div>
- </div>
- </div>
- <div class="thr_cont" v-if="info.rules && info.rules.rules9">
- <div class="thr_1">奖项设置与奖励办法</div>
- <div class="thr_2">
- <div v-html="info.rules.rules9"></div>
- </div>
- </div>
- <div class="thr_cont" v-if="info.rules && info.rules.rules10">
- <div class="thr_1">组织单位</div>
- <div class="thr_2">
- <div v-html="info.rules.rules10"></div>
- </div>
- </div>
- <div class="thr_cont" v-if="info.rules && info.rules.rules11">
- <div class="thr_1">赛事联络</div>
- <div class="thr_2">
- <div v-html="info.rules.rules11"></div>
- </div>
- </div>
- <div class="thr_cont" v-if="info.rules && info.rules.rules12">
- <div class="thr_1">赛事交流</div>
- <div class="thr_2">
- <div v-html="info.rules.rules12"></div>
- </div>
- </div>
- <div class="button" @click="toSign">活动报名</div>
- </div>
- </div>
- </div>
- </el-col>
- </custom-layout>
- <el-dialog v-model="dialog" title="活动报名" :destroy-on-close="true" @close="toClose">
- <data-form></data-form>
- </el-dialog>
- </template>
- <script setup>
- import moment from 'moment'
- import { get, cloneDeep } from 'lodash-es'
- const $checkRes = inject('$checkRes')
- // 组件
- import dataForm from './parts/index.vue'
- import time from '/images/time.png'
- import { UserStore } from '@/store/user'
- const userStore = UserStore()
- const user = computed(() => userStore.user)
- // 接口
- import { DictDataStore } from '@/store/api/system/dictData'
- import { MatchStore } from '@/store/api/platform/match'
- import { SignStore } from '@/store/api/platform/sign'
- const dictDataStore = DictDataStore()
- const store = MatchStore()
- const signStore = SignStore()
- // 加载中
- const loading = ref(false)
- // 路由
- const route = useRoute()
- const info = ref({})
- // 弹框
- const cardTypeList = ref([])
- const typeList = ref([])
- const ruleFormRef = ref()
- const form = ref({})
- const validatePhoneNumber = (rule, value, callback) => {
- const reg = /^1[3-9]\d{9}$/
- if (!value) {
- return callback(new Error('手机号不能为空'))
- }
- if (!reg.test(value)) {
- return callback(new Error('请输入正确的手机号'))
- }
- callback()
- }
- const validateCardNumber = (rule, value, callback) => {
- var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
- if (!value) {
- return callback(new Error('证件号码不能为空'))
- }
- if (!reg.test(value)) {
- return callback(new Error('请输入正确的证件号码'))
- }
- callback()
- }
- const rules = reactive({
- name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
- phone: [{ required: true, validator: validatePhoneNumber, trigger: 'blur' }],
- cardType: [{ required: true, message: '请选择证件类型', trigger: 'change' }],
- card: [{ required: true, validator: validateCardNumber, trigger: 'change' }],
- remark: [{ required: true, message: '请输入备注', trigger: 'blur' }]
- })
- const dialog = ref(false)
- // 请求
- onMounted(async () => {
- loading.value = true
- await searchOther()
- await search()
- loading.value = false
- })
- const searchOther = async () => {
- let result
- // 证件类型
- result = await dictDataStore.query({ code: 'cardType', is_use: '0' })
- if ($checkRes(result)) cardTypeList.value = result.data
- // 赛事类型
- result = await dictDataStore.query({ code: 'activeType', is_use: '0' })
- if ($checkRes(result)) typeList.value = result.data
- }
- const search = async () => {
- let id = route.query.id
- if (id) {
- let res = await store.fetch(id)
- if (res.errcode == '0') info.value = res.data
- }
- }
- // 字典数据转换
- const getDict = (data, model) => {
- if (data) {
- let res
- if (model == 'type') res = typeList.value.find((f) => f.value == data)
- return get(res, 'label')
- }
- }
- // 报名参赛
- const toSign = () => {
- if (info.value.match_type == '1') {
- window.open(info.value.href, '_blank') // 在新标签页中打开URL
- } else dialog.value = true
- }
- const toClose = () => {
- dialog.value = false
- form.value = {}
- }
- const getUrl = (item, type) => {
- if (item) {
- if (type == 'array') return `${import.meta.env.VITE_APP_HOST}${item[0].uri}`
- else return `${import.meta.env.VITE_APP_HOST}${item.uri}`
- }
- }
- // 报名
- const submitForm = async (formEl) => {
- if (user.value.id) {
- if (!formEl) return
- await formEl.validate(async (valid, fields) => {
- if (valid) {
- const data = cloneDeep(form.value)
- const other = {
- match: info.value.id,
- user: user.value.id,
- time: moment().format('YYYY-MM-DD')
- }
- let res = await signStore.create({ ...data, ...other })
- if ($checkRes(res, true)) toClose()
- } else {
- console.log('error submit!', fields)
- }
- })
- } else {
- ElMessage.error('用户未登录无法报名活动!')
- }
- }
- // provide
- provide('form', form)
- provide('rules', rules)
- provide('ruleFormRef', ruleFormRef)
- provide('cardTypeList', cardTypeList)
- provide('submitForm', submitForm)
- </script>
- <style scoped lang="scss">
- .main {
- .one {
- background: url(/images/matchBg.jpg) no-repeat;
- background-position: center top;
- .info_1 {
- padding: 90px 80px 0 80px;
- .name {
- font-size: $global-font-size-36;
- width: 50%;
- font-weight: bold;
- }
- .brief {
- font-size: $global-font-size-20;
- margin-top: 25px;
- color: #000;
- }
- .type {
- font-size: $global-font-size-12;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- width: 70px;
- height: 25px;
- border-radius: 4px;
- text-align: center;
- line-height: 25px;
- font-weight: 700;
- color: #2a78ff;
- background: #eaf1ff;
- }
- .time {
- display: flex;
- margin-top: 60px !important;
- color: #666;
- font-size: $global-font-size-16;
- .image {
- width: 18px;
- height: 18px;
- margin: 0 5px 0 0;
- }
- }
- .button {
- margin-top: 70px !important;
- justify-content: center;
- display: flex !important;
- align-items: center;
- width: 136px;
- height: 44px;
- color: #fff;
- font-size: 16px;
- background-image: linear-gradient(90deg, #0455da 0%, #378cff 100%), linear-gradient(#0455da, #0455da);
- background-blend-mode: normal, normal;
- border-radius: 4px;
- }
- }
- .info_2 {
- padding: 0 80px;
- margin-top: 70px !important;
- .title {
- color: #000;
- display: inline-block;
- padding-bottom: 20px;
- font-size: $global-font-size-30;
- border-bottom: 5px solid #378cff;
- cursor: pointer;
- }
- .content {
- display: flex;
- margin-top: 50px;
- .content_1 {
- height: 200px;
- width: 630px;
- text-indent: 2em;
- font-size: 16px;
- line-height: 36px;
- color: #333333;
- overflow: hidden;
- }
- .image {
- margin-left: 66px;
- width: 331px;
- height: 182px;
- }
- }
- }
- .info_3 {
- padding: 80px !important;
- margin-top: 50px !important;
- background: #fff;
- .title {
- color: #000;
- display: inline-block;
- padding-bottom: 20px;
- font-size: $global-font-size-30;
- border-bottom: 5px solid #378cff;
- cursor: pointer;
- }
- .content {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- .thr_cont {
- text-align: center;
- margin: 10px 0;
- width: 100%;
- .thr_1 {
- color: #000;
- display: inline-block;
- padding-bottom: 10px;
- border-bottom: 5px solid #378cff;
- font-size: $global-font-size-20;
- cursor: pointer;
- }
- .thr_2 {
- padding: 20px;
- }
- }
- .button {
- margin-top: 70px !important;
- justify-content: center;
- display: flex !important;
- align-items: center;
- width: 136px;
- height: 44px;
- color: #fff;
- font-size: 16px;
- background-image: linear-gradient(90deg, #0455da 0%, #378cff 100%), linear-gradient(#0455da, #0455da);
- background-blend-mode: normal, normal;
- border-radius: 4px;
- }
- }
- }
- }
- }
- </style>
|