| | |
| | | <template> |
| | | <view class="layout"> |
| | | <!-- 获取更多机会按钮 - 右上角悬浮 --> |
| | | <view class="floating-more-btn" @tap="showMoreChances"> |
| | | <text class="floating-btn-icon">🎁</text> |
| | | </view> |
| | | |
| | | <!-- 剩余抽奖次数 --> |
| | | <view class="remaining-times"> |
| | | <text class="times-label">剩余抽奖次数:</text> |
| | |
| | | <view class="prize-section"> |
| | | <view class="section-title">奖品池</view> |
| | | <view class="prize-grid"> |
| | | <view class="prize-item" v-for="(prize, index) in prizeList" :key="prize.id"> |
| | | <view class="prize-item" v-for="(prize, index) in prizeDraws" :key="prize.id"> |
| | | <image :src="prize.img" class="prize-img" /> |
| | | <text class="prize-name">{{ prize.name }}</text> |
| | | </view> |
| | |
| | | <!-- 最近中奖信息 --> |
| | | <view class="winners-section"> |
| | | <view class="section-title">最近中奖</view> |
| | | <scroll-view scroll-y="true" class="winners-list" :scroll-top="scrollTop" |
| | | > |
| | | <scroll-view scroll-y="true" class="winners-list" :scroll-top="scrollTop"> |
| | | <view class="winner-item" v-for="(winner, index) in recentWinners" :key="index"> |
| | | <text class="winner-name">{{ winner.nickname }}</text> |
| | | <text class="winner-prize">获得 {{ winner.prizeName }}</text> |
| | |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 获取更多抽奖机会弹窗 --> |
| | | <view class="more-chances-modal" v-if="showMoreChancesModal" @tap="closeMoreChancesModal"> |
| | | <view class="more-chances-modal-content" @tap.stop> |
| | | <view class="modal-close" @tap="closeMoreChancesModal">×</view> |
| | | |
| | | <view class="modal-title"> |
| | | <text class="title-icon">🎯</text> |
| | | <text class="title-text">获取更多抽奖机会</text> |
| | | </view> |
| | | |
| | | <view class="chances-grid"> |
| | | <button class="chance-item" open-type="share"> |
| | | <view class="chance-icon">👥</view> |
| | | <text class="chance-title">分享好友</text> |
| | | <text class="chance-subtitle">+1次机会</text> |
| | | </button> |
| | | <!-- <view class="chance-item" @tap="shareToTimeline"> |
| | | <view class="chance-icon">🌐</view> |
| | | <text class="chance-title">分享朋友圈</text> |
| | | <text class="chance-subtitle">+1次机会</text> |
| | | </view> --> |
| | | <view class="chance-item" @tap="watchVideo"> |
| | | <view class="chance-icon">🎬</view> |
| | | <text class="chance-title">浏览视频</text> |
| | | <text class="chance-subtitle">+1次机会</text> |
| | | </view> |
| | | <view class="chance-item" @tap="browseProduct"> |
| | | <view class="chance-icon">🛍️</view> |
| | | <text class="chance-title">浏览商品</text> |
| | | <text class="chance-subtitle">+1次机会</text> |
| | | </view> |
| | | <view class="chance-item " @tap="goShopping"> |
| | | <view class="chance-icon">🛒</view> |
| | | <text class="chance-title">去购物</text> |
| | | <text class="chance-subtitle">享受购物乐趣</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="modal-tip"> |
| | | <text class="tip-text">💡 完成任务即可获得额外抽奖机会</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | </template> |
| | |
| | | remainingTimes: 0, |
| | | // 弹窗控制 |
| | | showPrizeModal: false, |
| | | showMoreChancesModal: false, |
| | | currentPrize: {}, |
| | | // 自动滚动控制 |
| | | scrollTimer: null, |
| | |
| | | // 最近中奖信息 |
| | | originalWinners: [], |
| | | // 奖品列表, |
| | | prizeList: [] |
| | | prizeList: [], |
| | | prizeDraws: [], |
| | | // 分享朋友圈尝试标记 |
| | | shareTimelineAttempt: false, |
| | | activityCover:'', |
| | | activityName:'' |
| | | }; |
| | | }, |
| | | computed: { |
| | |
| | | } |
| | | }, |
| | | async onLoad(option) { |
| | | const pages = getCurrentPages() |
| | | console.log('================pages ',pages) |
| | | this.activityId = option.id |
| | | const prize = await prizeInfo(this.activityId); |
| | | this.activityCover = prize.data.data.activityCover |
| | | this.activityName = prize.data.data.activityName |
| | | console.log(prize.data) |
| | | this.prizeList = prize.data.data.prizeInfoVOS.map(item => { |
| | | return { |
| | |
| | | img: item.prizeImg |
| | | } |
| | | }) |
| | | this.prizeDraws = this.prizeList; |
| | | this.prizeList = [...this.prizeList] |
| | | this.prizeList.push({ |
| | | id: 'notWIn', |
| | | name: "谢谢参与" |
| | | name: "再来一次" |
| | | }) |
| | | await this.getUnmber(this.activityId) |
| | | await this.getGrantRecord(this.activityId) |
| | | }, |
| | | onShareTimeline(e){ |
| | | console.log('------------------>',e) |
| | | }, |
| | | // onShareTimeline(e) { |
| | | // console.log('------------------>', e) |
| | | // // 如果用户尝试过分享朋友圈,给予奖励 |
| | | // if (this.shareTimelineAttempt) { |
| | | // this.remainingTimes++; |
| | | // this.shareTimelineAttempt = false; |
| | | // uni.showToast({ |
| | | // title: '获得1次抽奖机会', |
| | | // icon: 'success' |
| | | // }); |
| | | // } |
| | | // return { |
| | | // title: '快来参与抽奖活动吧!', |
| | | // path: '/pages/prize/PrizeDetail/PrizeDetail?id=' + this.activityId |
| | | // } |
| | | // }, |
| | | //可能会使用到 |
| | | mounted() { |
| | | // this.startAutoScroll() |
| | | }, |
| | | onShareAppMessage() { |
| | | return{ |
| | | title: this.activityName, |
| | | path: '/pages/prize/PrizeDetail/PrizeDetail?id=' + this.activityId, |
| | | imageUrl:this.activityCover, |
| | | success(e) { |
| | | console.log("分享成功",e) |
| | | },fail(e) { |
| | | console.log('分享失败',e) |
| | | } |
| | | } |
| | | }, |
| | | beforeDestroy() { |
| | | this.stopAutoScroll() |
| | |
| | | closePrizeModal() { |
| | | this.showPrizeModal = false |
| | | this.currentPrize = {} |
| | | }, |
| | | // 显示获取更多机会弹窗 |
| | | showMoreChances() { |
| | | this.showMoreChancesModal = true |
| | | }, |
| | | // 关闭获取更多机会弹窗 |
| | | closeMoreChancesModal() { |
| | | this.showMoreChancesModal = false |
| | | }, |
| | | // 分享到微信好友 |
| | | shareToFriend() { |
| | | uni.showShareMenu({ |
| | | menus: ['weixin'], |
| | | success: (res) => { |
| | | console.log('分享菜单显示成功', res); |
| | | // 增加抽奖次数 |
| | | this.remainingTimes++; |
| | | // 关闭弹窗 |
| | | this.closeMoreChancesModal(); |
| | | uni.showToast({ |
| | | title: '获得1次抽奖机会', |
| | | icon: 'success' |
| | | }); |
| | | }, |
| | | fail: (err) => { |
| | | console.log('分享菜单显示失败', err); |
| | | uni.showToast({ |
| | | title: '分享失败', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }); |
| | | }, |
| | | // 分享到朋友圈 |
| | | shareToTimeline() { |
| | | // 由于uni-app的限制,朋友圈分享需要在onShareTimeline中处理 |
| | | // 这里我们先显示提示,然后通过右上角分享到朋友圈 |
| | | this.closeMoreChancesModal(); |
| | | uni.showModal({ |
| | | title: '分享到朋友圈', |
| | | content: '请点击右上角的分享按钮,选择"分享到朋友圈"', |
| | | showCancel: false, |
| | | success: () => { |
| | | // 标记用户已尝试分享朋友圈 |
| | | this.shareTimelineAttempt = true; |
| | | } |
| | | }); |
| | | }, |
| | | // 浏览视频 |
| | | watchVideo() { |
| | | // 这里可以跳转到视频页面或弹出视频播放器 |
| | | this.closeMoreChancesModal(); |
| | | uni.showModal({ |
| | | title: '浏览视频', |
| | | content: '即将跳转到视频页面', |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | // 模拟观看视频完成,增加抽奖次数 |
| | | // 这里可以添加跳转到具体视频页面的逻辑 |
| | | uni.navigateTo({ |
| | | url: '/pages/tabbar/index/home' |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | // 浏览商品 |
| | | browseProduct() { |
| | | // 跳转到商品页面 |
| | | this.closeMoreChancesModal(); |
| | | uni.showModal({ |
| | | title: '浏览商品', |
| | | content: '即将跳转到商品广场', |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | // 这里可以添加跳转到具体商品页面的逻辑 |
| | | uni.navigateTo({ |
| | | url: '/pages/commodity-square/commoditySquare' |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | // 去购物 |
| | | goShopping() { |
| | | this.closeMoreChancesModal(); |
| | | uni.showModal({ |
| | | title: '去购物', |
| | | content: '即将跳转到购物车', |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | // 或者跳转到购物车 |
| | | uni.navigateTo({ |
| | | url: '/pages/cusbar/cart/cartList' |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | async onClick() { |
| | | // 检查剩余次数 |
| | |
| | | font-weight: bold; |
| | | } |
| | | |
| | | /* 右上角悬浮获取更多机会按钮 */ |
| | | .floating-more-btn { |
| | | position: fixed; |
| | | top: 30rpx; |
| | | right: 30rpx; |
| | | width: 100rpx; |
| | | height: 100rpx; |
| | | background: linear-gradient(45deg, #ff6b6b, #feca57); |
| | | border-radius: 50%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | box-shadow: 0 6rpx 20rpx rgba(255, 107, 107, 0.4); |
| | | z-index: 999; |
| | | transition: all 0.3s ease; |
| | | } |
| | | |
| | | .floating-more-btn::before { |
| | | content: ''; |
| | | position: absolute; |
| | | width: 100%; |
| | | height: 100%; |
| | | border-radius: 50%; |
| | | background: linear-gradient(45deg, #ff6b6b, #feca57); |
| | | opacity: 0.8; |
| | | animation: pulse 2s infinite; |
| | | } |
| | | |
| | | @keyframes pulse { |
| | | 0% { |
| | | transform: scale(1); |
| | | opacity: 0.8; |
| | | } |
| | | |
| | | 50% { |
| | | transform: scale(1.1); |
| | | opacity: 0.4; |
| | | } |
| | | |
| | | 100% { |
| | | transform: scale(1); |
| | | opacity: 0.8; |
| | | } |
| | | } |
| | | |
| | | .floating-more-btn:active { |
| | | transform: scale(0.95); |
| | | box-shadow: 0 4rpx 15rpx rgba(255, 107, 107, 0.5); |
| | | } |
| | | |
| | | .floating-btn-icon { |
| | | font-size: 36rpx; |
| | | color: white; |
| | | z-index: 1; |
| | | position: relative; |
| | | filter: drop-shadow(0 2rpx 4rpx rgba(0, 0, 0, 0.2)); |
| | | } |
| | | |
| | | /* 奖品展示 */ |
| | | .prize-section { |
| | | width: 100%; |
| | |
| | | .prize-grid { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | justify-content: space-between; |
| | | justify-content: flex-start; |
| | | } |
| | | |
| | | .prize-item:nth-child(n+1){ |
| | | margin-left: 15rpx; |
| | | } |
| | | .prize-item { |
| | | width: 22%; |
| | | margin-bottom: 20rpx; |
| | |
| | | .confirm-btn::after { |
| | | border: none; |
| | | } |
| | | |
| | | /* 获取更多机会弹窗样式 */ |
| | | .more-chances-modal { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | background: rgba(0, 0, 0, 0.6); |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | z-index: 9999; |
| | | } |
| | | |
| | | .more-chances-modal-content { |
| | | background: white; |
| | | border-radius: 30rpx; |
| | | width: 90%; |
| | | max-width: 600rpx; |
| | | max-height: 80vh; |
| | | padding: 40rpx; |
| | | position: relative; |
| | | box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.3); |
| | | overflow-y: auto; |
| | | } |
| | | |
| | | .modal-title { |
| | | text-align: center; |
| | | margin-bottom: 40rpx; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | |
| | | .title-icon { |
| | | font-size: 50rpx; |
| | | margin-bottom: 15rpx; |
| | | display: block; |
| | | } |
| | | |
| | | .title-text { |
| | | font-size: 36rpx; |
| | | font-weight: bold; |
| | | color: #333; |
| | | } |
| | | |
| | | .chances-grid { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | justify-content: space-between; |
| | | gap: 20rpx; |
| | | margin-bottom: 30rpx; |
| | | } |
| | | .chances-grid button{ |
| | | padding: 25rpx 15rpx; |
| | | margin: 0; |
| | | line-height: normal; |
| | | border: none; |
| | | } |
| | | .chances-grid button::after{ |
| | | border: none; |
| | | } |
| | | .chance-item { |
| | | width: 45%; |
| | | background: linear-gradient(45deg, #ff6b6b, #feca57); |
| | | border-radius: 15rpx; |
| | | padding: 25rpx 15rpx; |
| | | text-align: center; |
| | | position: relative; |
| | | overflow: hidden; |
| | | transition: all 0.3s ease; |
| | | box-shadow: 0 4rpx 15rpx rgba(255, 107, 107, 0.3); |
| | | } |
| | | |
| | | .chance-item::before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: -50%; |
| | | left: -50%; |
| | | width: 200%; |
| | | height: 200%; |
| | | background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.2), transparent); |
| | | transform: rotate(45deg); |
| | | transition: all 0.6s ease; |
| | | opacity: 0; |
| | | } |
| | | |
| | | .chance-item:active::before { |
| | | opacity: 1; |
| | | transform: translateX(100%) translateY(100%) rotate(45deg); |
| | | } |
| | | |
| | | .chance-item:active { |
| | | transform: scale(0.98); |
| | | box-shadow: 0 2rpx 10rpx rgba(255, 107, 107, 0.4); |
| | | } |
| | | |
| | | .chance-item-large { |
| | | width: 100%; |
| | | background: linear-gradient(45deg, #feca57, #ff9ff3); |
| | | box-shadow: 0 4rpx 20rpx rgba(254, 202, 87, 0.3); |
| | | } |
| | | |
| | | .chance-item-large:active { |
| | | box-shadow: 0 2rpx 15rpx rgba(254, 202, 87, 0.4); |
| | | } |
| | | |
| | | .chance-icon { |
| | | font-size: 40rpx; |
| | | margin-bottom: 10rpx; |
| | | display: block; |
| | | filter: drop-shadow(0 2rpx 4rpx rgba(0, 0, 0, 0.1)); |
| | | } |
| | | |
| | | .chance-title { |
| | | display: block; |
| | | color: white; |
| | | font-size: 28rpx; |
| | | font-weight: bold; |
| | | margin-bottom: 5rpx; |
| | | text-shadow: 0 1rpx 3rpx rgba(0, 0, 0, 0.2); |
| | | } |
| | | |
| | | .chance-subtitle { |
| | | display: block; |
| | | color: rgba(255, 255, 255, 0.95); |
| | | font-size: 22rpx; |
| | | text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .modal-tip { |
| | | text-align: center; |
| | | padding: 20rpx; |
| | | background: linear-gradient(45deg, #f8f9ff, #e3f2fd); |
| | | border-radius: 15rpx; |
| | | border: 2rpx dashed #667eea; |
| | | } |
| | | |
| | | .tip-text { |
| | | color: #667eea; |
| | | font-size: 26rpx; |
| | | font-weight: 500; |
| | | } |
| | | </style> |