hookehuyr

feat(海报打卡): 添加页面状态管理及空状态处理

添加页面状态管理逻辑,包括正常状态、无打卡信息状态和无活动信息状态
为空状态添加UI展示和处理逻辑
优化组件显示条件,根据状态动态渲染
......@@ -15,6 +15,7 @@ declare module 'vue' {
NutActionSheet: typeof import('@nutui/nutui-taro')['ActionSheet']
NutButton: typeof import('@nutui/nutui-taro')['Button']
NutDatePicker: typeof import('@nutui/nutui-taro')['DatePicker']
NutDialog: typeof import('@nutui/nutui-taro')['Dialog']
NutImagePreview: typeof import('@nutui/nutui-taro')['ImagePreview']
NutInput: typeof import('@nutui/nutui-taro')['Input']
NutPicker: typeof import('@nutui/nutui-taro')['Picker']
......
<template>
<view class="poster-checkin-page bg-gray-50 h-screen flex flex-col">
<!-- 活动信息区域 -->
<view class="bg-white mx-4 mt-4 mb-2 rounded-lg shadow-sm p-4">
<view v-if="pageState === 'normal' || pageState === 'no-checkin'" class="bg-white mx-4 mt-4 mb-2 rounded-lg shadow-sm p-4">
<!-- 活动主题 -->
<view class="text-lg font-bold text-gray-800 mb-2">
{{ activityInfo.title }}
......@@ -27,8 +27,8 @@
</view>
</view>
<!-- 海报预览区域 -->
<view class="flex-1 mx-4 mb-2 bg-white rounded-lg shadow-sm relative" style="overflow: visible;">
<!-- 海报预览区域 - 正常状态 -->
<view v-if="pageState === 'normal'" class="flex-1 mx-4 mb-2 bg-white rounded-lg shadow-sm relative" style="overflow: visible;">
<view class="h-full relative bg-gray-100 flex items-center justify-center">
<view v-if="currentPoster.path" class="w-full h-full relative">
<image
......@@ -68,8 +68,18 @@
</view>
</view>
<!-- 底部操作按钮 -->
<view class="bg-white border-t border-gray-200 p-4 safe-area-bottom">
<!-- 没有打卡信息的空状态 -->
<view v-if="pageState === 'no-checkin'" class="flex-1 mx-4 mb-2 flex justify-center">
<view class="bg-white rounded-lg shadow-sm p-8 text-center max-w-sm">
<view class="text-6xl mb-4">📸</view>
<view class="text-lg font-bold text-gray-800 mb-2">打卡信息为空</view>
<view class="text-sm text-gray-500 mb-4">您还没有打卡记录,请先参加活动打卡后再来生成海报</view>
<view class="text-xs text-orange-500">完成打卡后即可生成专属海报</view>
</view>
</view>
<!-- 底部操作按钮 - 仅在正常状态显示 -->
<view v-if="pageState === 'normal'" class="bg-white border-t border-gray-200 p-4 safe-area-bottom">
<view class="flex gap-4">
<view
class="flex-1 bg-gradient-to-r from-orange-400 to-orange-500 text-white py-3 px-6 rounded-lg font-medium shadow-lg active:scale-95 transition-transform duration-150 flex items-center justify-center gap-2"
......@@ -88,9 +98,9 @@
</view>
</view>
<!-- 海报生成组件 -->
<!-- 海报生成组件 - 仅在正常状态显示 -->
<PosterBuilder
v-if="shouldGeneratePoster"
v-if="shouldGeneratePoster && pageState === 'normal'"
:config="posterConfig"
:show-loading="true"
@success="onPosterSuccess"
......@@ -104,6 +114,8 @@
:init-no="0"
@close="closePreview"
/>
</view>
</template>
......@@ -149,7 +161,7 @@ const pageParams = ref({
const previewVisible = ref(false)
const previewImages = ref([])
// 活动信息数据
// 活动信息数据 - 模拟不同状态,实际使用时从API获取
const activityInfo = ref({
title: '南京路乐龄时尚消费主题路线',
checkPoints: [
......@@ -164,7 +176,9 @@ const activityInfo = ref({
endDate: '2025年9月7日'
})
// 海报列表数据
// activityInfo.value = {};
// 海报列表数据 - 模拟不同状态,实际使用时从API获取
const posterList = ref([
{
id: 1,
......@@ -189,6 +203,30 @@ const posterList = ref([
}
])
// posterList.value = []
// 数据状态检查
const hasActivityInfo = computed(() => {
return activityInfo.value && activityInfo.value.title && activityInfo.value.checkPoints && activityInfo.value.checkPoints.length > 0
})
const hasCheckinInfo = computed(() => {
return posterList.value && posterList.value.length > 0
})
// 页面显示状态
const pageState = computed(() => {
if (!hasActivityInfo.value) {
return 'no-activity' // 没有活动信息
}
if (!hasCheckinInfo.value) {
return 'no-checkin' // 有活动信息但没有打卡信息
}
return 'normal' // 正常状态
})
// 当前海报
const currentPoster = computed(() => {
return posterList.value[currentPosterIndex.value] || { path: '', title: '' }
......@@ -572,6 +610,43 @@ const savePoster = () => {
}
})
}
/**
* 显示没有活动信息的确认对话框
*/
const showNoActivityConfirm = () => {
Taro.showModal({
title: '温馨提示',
content: '您还没有参加过活动,请先参加活动后再来生成海报',
showCancel: false,
confirmText: '知道了',
success: (res) => {
if (res.confirm) {
// 返回上一页
Taro.navigateBack({
delta: 1
})
}
}
})
}
/**
* 页面初始化
*/
onMounted(() => {
// 获取页面参数
const instance = Taro.getCurrentInstance()
if (instance.router && instance.router.params) {
pageParams.value = instance.router.params
}
// 检查页面状态
if (pageState.value === 'no-activity') {
// 没有活动信息,显示确认对话框
showNoActivityConfirm()
}
})
</script>
<style lang="less">
......