膳逸前端开发--小程序开发日记【五】

提示:本篇文章为学校项目实训的记录,所以可能会写的没头没尾的,不具有实际指导意义,因为是小组共同开发,所以不是自己负责的部分会在别的小组成员博客里。


前言

上次说到完成了发布打卡页面,现在进入下一个主题,活动页面。


一、活动主页

活动主页主要是以卡片的形式展示,卡片展示了活动主题和时效,点击后会进入活动详情页,详情页可参与,可打卡活动。

二、效果详述

1.我的活动主页详述

效果图如下
在这里插入图片描述

前端template代码如下:

		
<template>
    <view class="container">
        <view class="card" v-for="(item, index) in cards" :key="index">
            <image :src="item.picture" class="card-image"></image>
            <view class="card-content">
                <text class="card-title">{{ item.name }}</text>
                <view :class="['card-button', getButtonClass(item.check)]" @tap="handleButtonClick(item)">
                    <text class="button-text">{{ getButtonText(item.check) }}</text>
                </view>
            </view>
        </view>
    </view>
</template>

script代码如下,主要处理查询后返回的活动列表及其check值的不同情况。当活动check值为0(不在活动时间)和3(已完成)时,按钮没有跳转详情页面。

		
		fetchActivities() {
			console.log('调用到页面初始化方法')
            const data = {
                userId: this.userId,
                status: null,
                activityName: "",
                startTime: "",
                endTime: "",
                orderBy: "participants_count",
                order: "desc"
            };

            // 假设 ajax 方法已经定义并可用
            this.ajax(this.api.searchMyActivities, 'POST', data, (resp) => {
				console.log(resp)
                if (resp.data.code === 200) {
                    this.cards = resp.data.result;
                } else {
                    uni.showToast({
                        icon: 'error',
                        title: resp.msg || '加载失败'
                    });
                }
            });
        },
        getButtonText(check) {
            switch (check) {
                case 0:
                    return '不在活动时间';
                case 1:
                    return '去参与';
                case 2:
                    return '去打卡';
                case 3:
                    return '已完成';
                default:
                    return '';
            }
        },
        getButtonClass(check) {
            return {
                'disabled': check === 0,
                'participate': check === 1,
                'check-in': check === 2,
                'completed': check === 3
            };
        },
        handleButtonClick(item) {
            if (item.check === 0) {
                uni.showToast({
                    icon: 'none',
                    title: '活动未开始或已结束'
                });
                return;
            } else if (item.check === 1) {
				uni.setStorageSync('activityId', item.id)
                // 跳转到参与页面的逻辑
                uni.navigateTo({
                    url: '/user/activity_check/activity_check'
                });
            } else if (item.check === 2) {
				uni.setStorageSync('activityId', item.id)
                // 跳转到打卡页面的逻辑
                uni.navigateTo({
                    url: '/user/activity_check/activity_check'
                });
            } else if (item.check === 3) {
                uni.showToast({
                    icon: 'none',
                    title: '活动已完成'
                });
            }
        }
    },
    onShow() {
        this.fetchActivities();
        // 监听自定义事件
        this.$bus.$on('refreshActivity', this.fetchActivities);
    },
    onUnload() {
        // 组件销毁时,移除事件监听
        this.$bus.$off('refreshActivity', this.fetchActivities);
    },

2.活动详情页详述

当活动可以参与或打卡时,点击按钮进入活动详情页面。点击去打卡后会跳转到打卡发布页面。效果图如下:
在这里插入图片描述
活动详情页的template代码如下:

		
<template>
    <view class="container">
        <view class="card" v-if="activity">
            <image :src="activity.picture" class="card-image"></image>
            <view class="card-content">
				<u-row>
					<text class="card-title">{{ activity.name }}</text>
				</u-row>
                <u-row>
                	<text class="card-description">活动概述: {{ activity.description }}</text>
                </u-row>
				<u-row>
					<text class="card-requirements">详细要求: {{ activity.requirements }}</text>
				</u-row>
				<u-row>
					<text class="card-reward">活动奖励: {{ activity.reward }}</text>
				</u-row>
				<u-row>
					<text class="card-participants">可参与人数: {{ activity.participants_count }}</text>
				</u-row>
				<u-row>
					<text class="card-participants">要求打卡天数: {{ activity.count_day }}</text>
				</u-row>
                <u-row>
                	<text class="card-time">活动时间: {{ activity.start_time }} - {{ activity.end_time }}</text>
                </u-row>
				<u-row>
					<view class="card-button" @tap="handleButtonClick(activity)">
						<text class="button-text">{{ getButtonText(activity.check) }}</text>
					</view>
					<u-col span="5">
						
					</u-col>
					<text v-if="activity.check === 2 && checkInCount !== null" class="check-in-count">已打卡{{ checkInCount }}</text>
				</u-row>
            </view>
        </view>
		<!-- 确认参与弹窗 -->
        <u-popup :show="showConfirmPopup" mode="center" :round="10" @close="hideConfirmPopup">
            <view class="confirm-popup">
                <text class="popup-header">确认参与活动?</text>
                <view class="button-container">
                    <u-button type="primary" @click="confirmParticipation">确认</u-button>
                    <u-button type="default" @click="hideConfirmPopup">取消</u-button>
                </view>
            </view>
        </u-popup>
    </view>
</template>

页面跳转时只传递活动id,到达新页面会重新查询活动,选择id对应的活动进行卡片展示。

		
		fetchActivity() {
            const data = {
                userId: this.userId,
                status: null,
                activityName: "",
                startTime: "",
                endTime: "",
                orderBy: "participants_count",
                order: "desc"
            };

            // 假设 ajax 方法已经定义并可用
            this.ajax(this.api.searchMyActivities, 'POST', data, (resp) => {
				console.log('活动详细信息返回',resp)
                if (resp.data.code === 200) {
                    const activityId = uni.getStorageSync('activityId');
                    this.activity = resp.data.result.find(activity => activity.id === activityId);
					if (this.activity.check === 2) {
                        this.fetchCheckInCount();
                    }
				} else {
                    uni.showToast({
                        icon: 'error',
                        title: resp.msg || '加载失败'
                    });
                }
            });
        },
		fetchCheckInCount() {
            const data = {
                userId: this.userId,
                activityId: uni.getStorageSync('activityId')
            };
			console.log('请求数据',data)
            this.ajax(this.api.countMyActivityCheckIn, 'POST', data, (resp) => {
				console.log('打卡天数',resp)
                if (resp.data.code === 200) {
                    this.checkInCount = resp.data.result;
                } else {
                    uni.showToast({
                        icon: 'none',
                        title: '获取打卡天数失败'
                    });
                }
            });
        },
		getButtonText(check) {
            switch (check) {
                case 1:
                    return '去参与';
                case 2:
                    return '去打卡';
                case 3:
                    return '已完成';
                default:
                    return '';
            }
        },
        handleButtonClick(activity) {
            if (activity.check === 1) {
                this.selectedActivityId = activity.id;
                this.showConfirmPopup = true;
            } else if (activity.check === 2) {
                uni.navigateTo({
                    url: '/user/everyday_activity_check/everyday_activity_check'
                });
            } else if (activity.check === 3) {
                uni.showToast({
                    icon: 'none',
                    title: '活动已完成'
                });
            }
			
        },
        confirmParticipation() {
            const data = {
                userId: this.userId,
                activityId: this.selectedActivityId
            };
            this.ajax(this.api.participatingActivity, 'POST', data, (resp) => {
                if (resp.data.code === 200) {
                    uni.showToast({
                        icon: 'success',
                        title: '参与成功'
                    });
                    this.showConfirmPopup = false;
                    // 更新活动状态或刷新活动信息
                    this.fetchActivity();
					this.$bus.$emit('refreshActivity');
                } else {
                    uni.showToast({
                        icon: 'error',
                        title: resp.data.msg || '参与失败'
                    });
                }
            });
        },
        hideConfirmPopup() {
            this.showConfirmPopup = false;
        }

3.发布活动打卡页面

总体来说,发布活动打卡页面复用了日常打卡页面的部分代码。但是在图片分析部分有改动。效果图如下:
在这里插入图片描述
不同之处如下:

		
		checkActivity(uploadedUrls, callback) {
			uni.showLoading({
			    title: '正在验证图片...'
			});
            uni.request({
                url: 'https://u404380-b1e7-5555557b.westc.gpuhub.com:8443/check_activity',
                method: 'POST',
                data: {
                    activity_id: uni.getStorageSync('activityId'),
                    image_url: uploadedUrls[0]
                },
                success: (res) => {
					console.log('图片验证请求',res)
                    if (res.data.result === "true") {
						uni.showToast({
						    icon: 'none',
						    title: '图片验证通过'
						});
                        callback(true);
                    } else {
                        callback(false);
                    }
                },
                fail: () => {
                    uni.showToast({
                        icon: 'none',
                        title: '图片验证请求失败'
                    });
                    callback(false);
                }
            });
        },

同样的,也包含事件的监听,在活动详情页面中

	onShow() {
        this.fetchActivity();
        // 监听自定义事件
        this.$bus.$on('refreshActivityCheck', this.fetchActivity);
    },
    onUnload() {
        // 组件销毁时,移除事件监听
        this.$bus.$off('refreshActivityCheck', this.fetchActivity);
    },

总结

这次开发主要使用了卡片组件,复用了之前的一些代码,也用到了事件的监听。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kami447

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值