|
@@ -250,177 +250,6 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
-
|
|
|
|
|
- <!-- 空状态 -->
|
|
|
|
|
- <view v-else class="empty-wrap">
|
|
|
|
|
- <text class="empty-text">活动不存在或已下架</text>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 分享海报 -->
|
|
|
|
|
- <ContentSharePoster
|
|
|
|
|
- :show="showPoster"
|
|
|
|
|
- :title="activity && activity.title"
|
|
|
|
|
- :coverImage="activity && getImageUrl(activity.coverImage)"
|
|
|
|
|
- :qrCodeBase64="posterQrCode"
|
|
|
|
|
- typeLabel="活动推荐"
|
|
|
|
|
- :dimensionCode="activity && activity.dimensionCode"
|
|
|
|
|
- :summary="posterSummary"
|
|
|
|
|
- :priceText="posterPriceText"
|
|
|
|
|
- :inviteText="posterInviteText"
|
|
|
|
|
- @close="closePoster"
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <!-- 底部操作栏:必须与 scroll-view 平级,否则 iOS 上 position: fixed 在 scroll-view 内不生效(按钮不显示) -->
|
|
|
|
|
- <view class="bottom-bar" v-if="!loading && activity.id">
|
|
|
|
|
- <view class="price-info">
|
|
|
|
|
- <text class="bottom-type">活动</text>
|
|
|
|
|
- <text class="bottom-vendor" v-if="activity.vendorName">{{ activity.vendorName }}</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="action-btns">
|
|
|
|
|
- <button class="share-btn" @click="generatePoster">
|
|
|
|
|
- <text class="share-btn-icon">📤</text>
|
|
|
|
|
- <text class="share-btn-text">分享</text>
|
|
|
|
|
- </button>
|
|
|
|
|
- <!-- 报名按钮(仅报名中/未报名时显示) -->
|
|
|
|
|
- <button
|
|
|
|
|
- v-if="canRegister"
|
|
|
|
|
- class="btn-register"
|
|
|
|
|
- @click="onRegister"
|
|
|
|
|
- >
|
|
|
|
|
- <text v-if="hasFee">¥{{ minFeeText }} 立即报名</text>
|
|
|
|
|
- <text v-else>立即报名</text>
|
|
|
|
|
- </button>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 已报名待审核 -->
|
|
|
|
|
- <button
|
|
|
|
|
- v-if="activity.requireRegistration === 1 && registrationStatus === 'pending'"
|
|
|
|
|
- class="btn-register-done"
|
|
|
|
|
- disabled
|
|
|
|
|
- >
|
|
|
|
|
- <text>报名待审核</text>
|
|
|
|
|
- </button>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 已报名可取消 -->
|
|
|
|
|
- <button
|
|
|
|
|
- v-if="activity.requireRegistration === 1 && (registrationStatus === 'approved' || registrationStatus === 'registered')"
|
|
|
|
|
- class="btn-cancel"
|
|
|
|
|
- :disabled="registrationLoading"
|
|
|
|
|
- @click="onCancelRegistration"
|
|
|
|
|
- >
|
|
|
|
|
- <text>取消报名</text>
|
|
|
|
|
- </button>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 签到按钮(仅进行中时显示) -->
|
|
|
|
|
- <button
|
|
|
|
|
- v-if="activity.displayStatus === 'ongoing'"
|
|
|
|
|
- class="btn-checkin"
|
|
|
|
|
- :class="{ 'btn-checkin-done': checkinDone, 'btn-checkin-loading': checkinLoading }"
|
|
|
|
|
- :disabled="checkinLoading || checkinDone"
|
|
|
|
|
- @click="onCheckin"
|
|
|
|
|
- >
|
|
|
|
|
- <text v-if="checkinLoading">签到中...</text>
|
|
|
|
|
- <text v-else-if="checkinDone && activity.requireCheckinReview === 1">已签到待审核</text>
|
|
|
|
|
- <text v-else-if="checkinDone">已签到 ✓</text>
|
|
|
|
|
- <text v-else>签到</text>
|
|
|
|
|
- </button>
|
|
|
|
|
- <text v-if="activity.requireCheckinReview === 1 && !checkinDone && activity.displayStatus === 'ongoing'" class="checkin-review-hint">签到需要管理员审核</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 能量扣减提示弹窗 -->
|
|
|
|
|
- <modal v-if="showPenaltyModal" class="penalty-modal" :show="showPenaltyModal" @close="showPenaltyModal = false">
|
|
|
|
|
- <view class="penalty-content">
|
|
|
|
|
- <text class="penalty-title">签到成功但已扣能量</text>
|
|
|
|
|
- <text class="penalty-desc">您未报名参加此活动,已被扣除 {{ penaltyAmount }} 点能量值</text>
|
|
|
|
|
- <button class="penalty-btn" @click="showPenaltyModal = false">我知道了</button>
|
|
|
|
|
- </view>
|
|
|
|
|
- </modal>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 评价弹窗 -->
|
|
|
|
|
- <modal v-if="showFeedbackModal" class="feedback-modal-overlay" :show="showFeedbackModal" @close="showFeedbackModal = false">
|
|
|
|
|
- <view class="feedback-modal">
|
|
|
|
|
- <text class="feedback-modal-title">活动评价</text>
|
|
|
|
|
-
|
|
|
|
|
- <view class="rating-row" v-for="(dim, dimIdx) in feedbackDimensions" :key="dimIdx">
|
|
|
|
|
- <text class="rating-label">{{ dim }}</text>
|
|
|
|
|
- <view class="stars">
|
|
|
|
|
- <text v-for="star in 5" :key="star"
|
|
|
|
|
- class="star-icon"
|
|
|
|
|
- :class="{'star-active': star <= (feedbackRatings[dim] || 0)}"
|
|
|
|
|
- @click="feedbackRatings[dim] = star">★</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <textarea class="feedback-textarea" v-model="feedbackComment" placeholder="说说您的体验..." maxlength="500" />
|
|
|
|
|
-
|
|
|
|
|
- <view class="feedback-modal-actions">
|
|
|
|
|
- <button class="feedback-cancel-btn" @click="showFeedbackModal = false">取消</button>
|
|
|
|
|
- <button class="feedback-submit-btn" :disabled="feedbackSubmitting" @click="submitFeedback">
|
|
|
|
|
- <text v-if="feedbackSubmitting">提交中...</text>
|
|
|
|
|
- <text v-else>提交评价</text>
|
|
|
|
|
- </button>
|
|
|
|
|
- </view>
|
|
|
|
|
- </view>
|
|
|
|
|
- </modal>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 报名表单弹窗 -->
|
|
|
|
|
- <view v-if="showRegModal" class="reg-modal-overlay" @click.self="closeRegModal">
|
|
|
|
|
- <view class="reg-modal">
|
|
|
|
|
- <text class="reg-modal-title">活动报名</text>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 家庭成员选择 -->
|
|
|
|
|
- <view class="reg-family-section" v-if="familyMembers.length > 0">
|
|
|
|
|
- <text class="reg-section-label">从家庭成员中选择</text>
|
|
|
|
|
- <view class="reg-family-list">
|
|
|
|
|
- <view
|
|
|
|
|
- class="reg-family-item"
|
|
|
|
|
- v-for="member in familyMembers"
|
|
|
|
|
- :key="member.id"
|
|
|
|
|
- :class="{'reg-family-item-selected': isMemberSelected(member)}"
|
|
|
|
|
- @click="toggleFamilyMember(member)"
|
|
|
|
|
- >
|
|
|
|
|
- <view class="reg-family-info">
|
|
|
|
|
- <text class="reg-family-name">{{ member.name }}</text>
|
|
|
|
|
- <text class="reg-family-relation">{{ member.relation }}</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <text class="reg-checkmark" v-if="isMemberSelected(member)">✓</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- </view>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 报名人列表 -->
|
|
|
|
|
- <view class="reg-list">
|
|
|
|
|
- <text class="reg-section-label">报名人</text>
|
|
|
|
|
- <view class="reg-entry" v-for="(entry, idx) in registrants" :key="idx">
|
|
|
|
|
- <input class="reg-input reg-input-name" v-model="entry.name" placeholder="姓名" />
|
|
|
|
|
- <input class="reg-input reg-input-phone" v-model="entry.phone" placeholder="手机号" type="number" maxlength="11" />
|
|
|
|
|
- <text class="reg-remove" @click="removeRegistrant(idx)">✕</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <button class="reg-add-btn" @click="addManualEntry">+ 添加报名人</button>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 合计 -->
|
|
|
|
|
- <view class="reg-total" v-if="hasFee">
|
|
|
|
|
- <text>共 {{ registrants.length }} 人 · 合计 ¥{{ registrantsTotal }}</text>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 操作按钮 -->
|
|
|
|
|
- <view class="reg-actions">
|
|
|
|
|
- <button class="reg-cancel" @click="closeRegModal">取消</button>
|
|
|
|
|
- <button class="reg-submit" :disabled="regSubmitting || registrants.length === 0" @click="submitRegistration">
|
|
|
|
|
- <text v-if="regSubmitting">提交中...</text>
|
|
|
|
|
- <text v-else>确认报名</text>
|
|
|
|
|
- </button>
|
|
|
|
|
- </view>
|
|
|
|
|
- </view>
|
|
|
|
|
- </view>
|
|
|
|
|
- </scroll-view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 空状态 -->
|
|
|
|
|
- <view v-else class="empty-wrap">
|
|
|
|
|
- <text class="empty-text">活动不存在或已下架</text>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
<!-- 分享海报 -->
|
|
<!-- 分享海报 -->
|
|
|
<ContentSharePoster
|
|
<ContentSharePoster
|
|
|
:show="showPoster"
|
|
:show="showPoster"
|