Files
danyang-match/h5-demo/src/pages/activity/ActivityRegisterPage.vue
T
WorkBuddy 69ebf33e18
CI/CD Pipeline / Backend Build & Test (push) Canceled after 0s
CI/CD Pipeline / Admin Web Build (push) Canceled after 0s
CI/CD Pipeline / Mini Program Compile Check (push) Canceled after 0s
CI/CD Pipeline / Migration Validation (push) Canceled after 0s
CI/CD Pipeline / Test Shell Guard (Phase 23 Gate) (push) Canceled after 0s
CI/CD Pipeline / UI Contracts (source-structure gates) (push) Canceled after 0s
CI/CD Pipeline / E2E (live stack) (push) Canceled after 0s
release: freeze demo v1.1.0 2026-10-19
2026-10-19 20:36:22 +08:00

148 lines
3.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<PageLayout title="活动报名">
<UiLoading v-if="loading" text="正在加载活动…" />
<UiErrorState v-else-if="error" @retry="load" />
<UiEmpty v-else-if="!activity" description="该活动不存在或已下线" />
<template v-else>
<div class="reg">
<div class="reg__card">
<div class="reg__title">{{ activity.title }}</div>
<div class="reg__meta">
<span>{{ formatDateTime(activity.startAt) || '时间待定' }}</span>
<span v-if="activity.locationName">{{ activity.locationName }}</span>
</div>
</div>
<div class="reg__card">
<div class="reg__label">备注 / 留言(选填)</div>
<van-field
v-model="remark"
type="textarea"
rows="3"
maxlength="200"
show-word-limit
placeholder="可填写方便工作人员联系的信息或特殊说明"
autosize
/>
</div>
<div class="reg__notice">
报名提交后需等待工作人员审核;不同活动类型的资格要求以活动页面和审核结果为准。
</div>
<van-button
class="reg__submit"
type="primary"
block
round
:loading="submitting"
@click="onSubmit"
>
提交报名
</van-button>
</div>
</template>
</PageLayout>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { activityService } from '@/api/services'
import { useAppStore } from '@/stores/app'
import { formatDateTime } from '@/utils/datetime'
import PageLayout from '@/layouts/PageLayout.vue'
import UiLoading from '@/components/UiLoading.vue'
import UiEmpty from '@/components/UiEmpty.vue'
import UiErrorState from '@/components/UiErrorState.vue'
const route = useRoute()
const router = useRouter()
const appStore = useAppStore()
const activityId = computed(() => String(route.query.id || ''))
const activity = ref<any>(null)
const loading = ref(true)
const error = ref(false)
const remark = ref('')
const submitting = ref(false)
async function load() {
loading.value = true
error.value = false
try {
if (!activityId.value) {
activity.value = null
return
}
activity.value = await activityService.getActivityDetail(activityId.value)
} catch (err: any) {
error.value = true
appStore.toastError(err?.message || '加载活动失败')
} finally {
loading.value = false
}
}
async function onSubmit() {
if (submitting.value || !activityId.value) return
submitting.value = true
try {
const payload = remark.value.trim() ? { remark: remark.value.trim() } : {}
await activityService.register(activityId.value, payload)
appStore.toastSuccess('报名已提交,请等待审核')
router.replace({ path: '/my/activities' })
} catch (err: any) {
appStore.toastError(err?.message || '报名失败')
} finally {
submitting.value = false
}
}
onMounted(load)
</script>
<style scoped>
.reg {
padding: 16px 16px 24px;
}
.reg__card {
background: var(--mini-surface);
border-radius: var(--mini-radius);
padding: 14px;
box-shadow: var(--mini-shadow);
margin-bottom: 12px;
}
.reg__title {
font-size: 16px;
font-weight: 600;
color: var(--mini-text-strong);
}
.reg__meta {
display: flex;
gap: 12px;
font-size: 12px;
color: var(--mini-text-secondary);
margin-top: 6px;
}
.reg__label {
font-size: 13px;
color: var(--mini-text-strong);
margin-bottom: 8px;
}
.reg__card :deep(.van-field) {
background: var(--mini-bg);
border-radius: 8px;
padding: 10px;
}
.reg__notice {
font-size: 12px;
color: var(--mini-text-muted);
line-height: 1.6;
margin: 4px 4px 16px;
}
.reg__submit {
margin-top: 8px;
}
</style>