687 lines
17 KiB
Vue
687 lines
17 KiB
Vue
<template>
|
||
<div class="registration-page">
|
||
<!-- 页面标题 -->
|
||
<div class="page-header">
|
||
<div class="header-title">活动报名</div>
|
||
<div class="header-subtitle">请填写以下信息完成报名</div>
|
||
</div>
|
||
|
||
<!-- 活动信息卡片 -->
|
||
<div class="event-info-card" v-if="eventInfo.ACTIVITY_ID">
|
||
<div class="event-cover">
|
||
<swiper>
|
||
<swiper-item v-for="(item, imgIndex) in eventInfo.ImageList" :key="imgIndex">
|
||
<image class="cover-image" :src="item.ImageUrl" mode="aspectFill" />
|
||
</swiper-item>
|
||
</swiper>
|
||
</div>
|
||
<div class="event-summary">
|
||
<div class="event-name">{{ eventInfo.ACTIVITY_NAME }}</div>
|
||
<div class="event-meta">
|
||
<div class="meta-item">
|
||
<span class="meta-icon">📅</span>
|
||
<span class="meta-text">{{ eventInfo.ACTIVITY_STARTDATE ? eventInfo.ACTIVITY_STARTDATE : ""
|
||
}}{{ eventInfo.ACTIVITY_ENDDATE ? `-` + eventInfo.ACTIVITY_ENDDATE : "" }}</span>
|
||
</div>
|
||
<div class="meta-item">
|
||
<span class="meta-icon">📍</span>
|
||
<span class="meta-text">{{ eventInfo.ACTIVITY_LOCATION }}</span>
|
||
</div>
|
||
<div class="meta-item">
|
||
<span class="meta-icon">👥</span>
|
||
<span class="meta-text">限{{ eventInfo.MAXIMUM_CAPACITY }}人</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 报名表单 -->
|
||
<div class="form-section">
|
||
<!-- 报名人姓名 -->
|
||
<div class="form-item">
|
||
<div class="item-label">
|
||
<span class="required">*</span>
|
||
报名人姓名
|
||
</div>
|
||
<input class="item-input" v-model="formData.participantName" placeholder="请输入您的真实姓名" />
|
||
</div>
|
||
|
||
<!-- 手机号码 -->
|
||
<div class="form-item">
|
||
<div class="item-label">
|
||
<span class="required">*</span>
|
||
手机号码
|
||
</div>
|
||
<input class="item-input" v-model="formData.phoneNumber" type="number" placeholder="请输入手机号码" maxlength="11" />
|
||
</div>
|
||
|
||
<!-- 备注信息 -->
|
||
<div class="form-item">
|
||
<div class="item-label">备注信息</div>
|
||
<textarea class="item-textarea" v-model="formData.remarks" placeholder="如有特殊需求请在此填写" :maxlength="500" />
|
||
</div>
|
||
|
||
<!-- 同意条款 -->
|
||
<div class="agreement-section">
|
||
<div class="agreement-item">
|
||
<div class="checkbox-wrapper" @click="toggleAgreement">
|
||
<div class="checkbox" :class="{ checked: formData.agreement }">
|
||
<div class="check-icon" v-if="formData.agreement">✓</div>
|
||
</div>
|
||
</div>
|
||
<span class="agreement-text">
|
||
我已阅读并同意
|
||
<text class="agreement-link" @click="showTerms">《活动参与条款》</text>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 提交按钮 -->
|
||
<div class="action-section">
|
||
<div class="action-btn" :class="[
|
||
mode === 'view' ? 'action-disabled' : 'primary-btn'
|
||
]" @click="handleSubmit">
|
||
<span class="btn-text">提交报名</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 条款弹窗 -->
|
||
<div class="terms-modal" v-if="showTermsModal" @click="hideTerms">
|
||
<div class="modal-content" @click.stop>
|
||
<div class="modal-header">
|
||
<div class="modal-title">活动参与条款</div>
|
||
<div class="close-btn" @click="hideTerms">×</div>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="terms-content">
|
||
<div class="terms-section">
|
||
<div class="section-title">1. 报名须知</div>
|
||
<div class="section-content">
|
||
• 请确保填写信息真实有效<br>
|
||
• 每人限报名一个活动<br>
|
||
• 报名成功后请按时参加<br>
|
||
• 如需取消报名,请提前24小时联系客服
|
||
</div>
|
||
</div>
|
||
<div class="terms-section">
|
||
<div class="section-title">2. 参与要求</div>
|
||
<div class="section-content">
|
||
• 请携带有效身份证件<br>
|
||
• 遵守现场秩序和工作人员指引<br>
|
||
• 保管好个人财物<br>
|
||
• 禁止携带危险物品入场
|
||
</div>
|
||
</div>
|
||
<div class="terms-section">
|
||
<div class="section-title">3. 免责声明</div>
|
||
<div class="section-content">
|
||
• 参与活动期间,请自行注意人身安全<br>
|
||
• 主办方对意外伤害不承担责任<br>
|
||
• 如遇不可抗力因素,活动可能调整或取消<br>
|
||
• 参与者表示同意上述条款
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<div class="modal-btn" @click="hideTerms">我知道了</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { mapGetters } from "vuex";
|
||
export default {
|
||
data() {
|
||
return {
|
||
eventId: "",
|
||
mode: "register", // register: 报名, view: 查看报名信息
|
||
eventInfo: {},
|
||
formData: {
|
||
participantName: "", // 报名人姓名
|
||
phoneNumber: "", // 手机号码
|
||
remarks: "", // 备注信息
|
||
agreement: false // 是否同意条款
|
||
},
|
||
showTermsModal: false,
|
||
defaultCover: 'https://picsum.photos/seed/event-registration/400/300.jpg'
|
||
};
|
||
},
|
||
computed: {
|
||
...mapGetters({
|
||
user: "user",
|
||
}),
|
||
},
|
||
onLoad(query) {
|
||
if (query.eventId) {
|
||
this.eventId = query.eventId;
|
||
}
|
||
|
||
if (query.mode) {
|
||
this.mode = query.mode;
|
||
}
|
||
|
||
this.loadEventInfo();
|
||
},
|
||
methods: {
|
||
// 加载活动信息
|
||
async loadEventInfo() {
|
||
const req = {
|
||
ACTIVITYId: this.eventId,
|
||
type: 'encryption'
|
||
}
|
||
uni.showLoading({
|
||
title: '加载中...',
|
||
mask: true
|
||
});
|
||
const data = await this.$api.$posMemberPost("/Member/GetACTIVITYDetail", req)
|
||
uni.hideLoading();
|
||
|
||
let detail = data.Result_Data
|
||
console.log('详情djaksjda', detail);
|
||
|
||
this.eventInfo = detail;
|
||
},
|
||
|
||
// 加载已报名信息
|
||
async loadRegistrationInfo() {
|
||
try {
|
||
// 这里调用接口获取用户的报名信息
|
||
// const res = await this.$api.getRegistrationInfo({
|
||
// eventId: this.eventId
|
||
// });
|
||
|
||
// 模拟已报名数据
|
||
this.formData = {
|
||
participantName: "张三",
|
||
phoneNumber: "13800138000",
|
||
email: "zhangsan@example.com",
|
||
idCard: "530102199001011234",
|
||
address: "云南省昆明市五华区xxx街道xxx号",
|
||
remarks: "需要特殊座位安排",
|
||
agreement: true
|
||
};
|
||
|
||
} catch (error) {
|
||
console.error('加载报名信息失败:', error);
|
||
}
|
||
},
|
||
|
||
// 切换同意条款状态
|
||
toggleAgreement() {
|
||
this.formData.agreement = !this.formData.agreement;
|
||
},
|
||
|
||
// 显示条款
|
||
showTerms() {
|
||
this.showTermsModal = true;
|
||
},
|
||
|
||
// 隐藏条款
|
||
hideTerms() {
|
||
this.showTermsModal = false;
|
||
},
|
||
|
||
// 格式化日期时间
|
||
formatDateTime(dateTime) {
|
||
if (!dateTime) return '';
|
||
try {
|
||
const date = new Date(dateTime);
|
||
const month = date.getMonth() + 1;
|
||
const day = date.getDate();
|
||
const hours = date.getHours().toString().padStart(2, '0');
|
||
const minutes = date.getMinutes().toString().padStart(2, '0');
|
||
return `${month}月${day}日 ${hours}:${minutes}`;
|
||
} catch (error) {
|
||
return dateTime;
|
||
}
|
||
},
|
||
|
||
// 验证表单
|
||
validateForm() {
|
||
if (!this.formData.participantName.trim()) {
|
||
uni.showToast({
|
||
title: "请输入报名人姓名",
|
||
icon: "none",
|
||
});
|
||
return false;
|
||
}
|
||
|
||
if (!this.formData.phoneNumber.trim()) {
|
||
uni.showToast({
|
||
title: "请输入手机号码",
|
||
icon: "none",
|
||
});
|
||
return false;
|
||
}
|
||
|
||
if (!/^1[3-9]\d{9}$/.test(this.formData.phoneNumber)) {
|
||
uni.showToast({
|
||
title: "请输入正确的手机号码",
|
||
icon: "none",
|
||
});
|
||
return false;
|
||
}
|
||
|
||
if (!this.formData.agreement) {
|
||
uni.showToast({
|
||
title: "请阅读并同意活动参与条款",
|
||
icon: "none",
|
||
});
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
},
|
||
|
||
// 提交报名
|
||
async handleSubmit() {
|
||
if (!this.validateForm()) {
|
||
return;
|
||
}
|
||
|
||
if (this.mode === 'view') {
|
||
uni.showToast({
|
||
title: '这是查看模式,无法修改',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
|
||
// 准备提交数据
|
||
const submitData = {
|
||
eventId: this.eventId,
|
||
...this.formData
|
||
};
|
||
|
||
console.log('submitData', submitData);
|
||
|
||
|
||
const req = {
|
||
ACTIVITY_ID: this.eventId,
|
||
MEMBERSHIP_ID: this.user.MEMBERSHIP_ID,
|
||
MEMBERSHIP_NAME: submitData.participantName,
|
||
MEMBERSHIP_MOBILEPHONE: submitData.phoneNumber,
|
||
ACTIVITYDETAIL_DESC: submitData.remarks,
|
||
ACTIVITYDETAIL_STATE: 1,
|
||
STAFF_ID: this.user.MEMBERSHIP_ID,
|
||
STAFF_NAME: this.user.MEMBERSHIP_NAME,
|
||
OPERATE_DATE: this.$moment.now().format("YYYY-MM-DD HH:mm:ss"),
|
||
type: 'encryption'
|
||
}
|
||
uni.showLoading({
|
||
title: "提交中...",
|
||
mask: true,
|
||
});
|
||
|
||
const data = await this.$api.$posMemberPost("/Member/SynchroACTIVITYDETAIL", req)
|
||
uni.hideLoading();
|
||
console.log('报名结果', data);
|
||
if (data.Result_Code === 100) {
|
||
uni.showModal({
|
||
title: "报名成功",
|
||
content: "您已成功报名该活动,请按时参加!",
|
||
showCancel: false,
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
uni.navigateBack();
|
||
}
|
||
},
|
||
});
|
||
} else {
|
||
uni.showToast({
|
||
title: data.Result_Desc,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped lang="less">
|
||
.registration-page {
|
||
width: 100vw;
|
||
min-height: 100vh;
|
||
background: #f8fafc;
|
||
overflow-y: scroll;
|
||
|
||
.page-header {
|
||
background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%);
|
||
padding: 60rpx 40rpx 40rpx;
|
||
text-align: center;
|
||
|
||
.header-title {
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
color: white;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
|
||
.header-subtitle {
|
||
font-size: 24rpx;
|
||
color: rgba(255, 255, 255, 0.9);
|
||
}
|
||
}
|
||
|
||
.event-info-card {
|
||
background: white;
|
||
margin: -20rpx 32rpx 32rpx;
|
||
border-radius: 24rpx 24rpx;
|
||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||
overflow: hidden;
|
||
|
||
.event-cover {
|
||
width: 100%;
|
||
height: 300rpx;
|
||
overflow: hidden;
|
||
|
||
.cover-image {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
}
|
||
}
|
||
|
||
.event-summary {
|
||
padding: 32rpx;
|
||
|
||
.event-name {
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
color: #1f2937;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
|
||
.event-meta {
|
||
.meta-item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 12rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.meta-icon {
|
||
font-size: 24rpx;
|
||
margin-right: 12rpx;
|
||
width: 32rpx;
|
||
text-align: center;
|
||
}
|
||
|
||
.meta-text {
|
||
font-size: 24rpx;
|
||
color: #6b7280;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.form-section {
|
||
padding: 40rpx 32rpx 24rpx;
|
||
background: white;
|
||
margin: 0 32rpx 0;
|
||
border-radius: 24rpx;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
|
||
margin-bottom: calc(160rpx + env(safe-area-inset-bottom));
|
||
box-sizing: border-box;
|
||
|
||
.form-item {
|
||
margin-bottom: 24rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.item-label {
|
||
font-size: 24rpx;
|
||
color: #374151;
|
||
font-weight: 500;
|
||
margin-bottom: 16rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.required {
|
||
color: #ef4444;
|
||
margin-right: 4rpx;
|
||
}
|
||
}
|
||
|
||
.item-input {
|
||
width: 100%;
|
||
height: 66rpx;
|
||
padding: 0 24rpx;
|
||
border: 2rpx solid #e5e7eb;
|
||
border-radius: 16rpx;
|
||
font-size: 24rpx;
|
||
color: #374151;
|
||
background: #f9fafb;
|
||
box-sizing: border-box;
|
||
|
||
&:focus {
|
||
border-color: #22c55e;
|
||
background: white;
|
||
}
|
||
|
||
&::placeholder {
|
||
color: #9ca3af;
|
||
}
|
||
}
|
||
|
||
.item-textarea {
|
||
width: 100%;
|
||
min-height: 160rpx;
|
||
padding: 20rpx 24rpx;
|
||
border: 2rpx solid #e5e7eb;
|
||
border-radius: 16rpx;
|
||
font-size: 24rpx;
|
||
color: #374151;
|
||
background: #f9fafb;
|
||
box-sizing: border-box;
|
||
resize: none;
|
||
|
||
&:focus {
|
||
border-color: #22c55e;
|
||
background: white;
|
||
}
|
||
|
||
&::placeholder {
|
||
color: #9ca3af;
|
||
}
|
||
}
|
||
}
|
||
|
||
.agreement-section {
|
||
.agreement-item {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
padding: 20rpx;
|
||
|
||
.checkbox-wrapper {
|
||
margin-right: 16rpx;
|
||
padding: 4rpx;
|
||
|
||
.checkbox {
|
||
width: 24rpx;
|
||
height: 24rpx;
|
||
border: 2rpx solid #d1d5db;
|
||
border-radius: 6rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.3s ease;
|
||
|
||
&.checked {
|
||
background: #22c55e;
|
||
border-color: #22c55e;
|
||
|
||
.check-icon {
|
||
color: white;
|
||
font-size: 24rpx;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.agreement-text {
|
||
font-size: 24rpx;
|
||
color: #374151;
|
||
line-height: 1.5;
|
||
|
||
.agreement-link {
|
||
color: #22c55e;
|
||
text-decoration: underline;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.action-section {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: #fff;
|
||
border-top: 1rpx solid #f0f0f0;
|
||
padding: 24rpx 32rpx calc(24rpx + env(safe-area-inset-bottom));
|
||
z-index: 100;
|
||
|
||
.action-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 24rpx;
|
||
border-radius: 40rpx;
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
transition: all 0.3s ease;
|
||
border: 2rpx solid #e5e7eb;
|
||
height: 40rpx;
|
||
|
||
&.primary-btn {
|
||
background: linear-gradient(135deg, #22c55e, #16a34a);
|
||
color: white;
|
||
border-color: #22c55e;
|
||
|
||
&:active {
|
||
opacity: 0.9;
|
||
}
|
||
|
||
.btn-text {
|
||
margin-right: 12rpx;
|
||
}
|
||
|
||
.btn-icon {
|
||
font-size: 28rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.terms-modal {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.5);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 1000;
|
||
|
||
.modal-content {
|
||
background: white;
|
||
border-radius: 24rpx;
|
||
margin: 40rpx;
|
||
width: calc(100% - 80rpx);
|
||
max-height: 80vh;
|
||
overflow: hidden;
|
||
|
||
.modal-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 32rpx;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
|
||
.modal-title {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #1f2937;
|
||
}
|
||
|
||
.close-btn {
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 50%;
|
||
background: #f3f4f6;
|
||
font-size: 32rpx;
|
||
color: #6b7280;
|
||
}
|
||
}
|
||
|
||
.modal-body {
|
||
padding: 32rpx;
|
||
max-height: 60vh;
|
||
overflow-y: auto;
|
||
|
||
.terms-content {
|
||
.terms-section {
|
||
margin-bottom: 32rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #1f2937;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.section-content {
|
||
font-size: 26rpx;
|
||
color: #6b7280;
|
||
line-height: 1.6;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.modal-footer {
|
||
padding: 32rpx;
|
||
border-top: 1rpx solid #f0f0f0;
|
||
|
||
.modal-btn {
|
||
width: 100%;
|
||
padding: 24rpx;
|
||
background: linear-gradient(135deg, #22c55e, #16a34a);
|
||
color: white;
|
||
border-radius: 16rpx;
|
||
font-size: 28rpx;
|
||
font-weight: 500;
|
||
text-align: center;
|
||
box-sizing: border-box;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.registration-page::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
</style> |