814 lines
18 KiB
Vue
Raw Normal View History

<template>
<view class="page">
<!-- <view style="position: fixed;left:0px;z-index: 100;" :style="{'top': statusBaeHeight + 58 + 'px'}">
<view class="search-box" style="background: #F2F2F2;">
<input type="text" disabled placeholder="搜索酒款/酒厂" @click="toSearch">
</view>
</view> -->
<view v-if="showJoinImg && bannerJoin" class="join-box" @click="toJoin">
<image :src="bannerJoin.bannerUrl" class="img" mode="aspectFill" :lazy-load="true"></image>
</view>
<!-- 轮播 -->
<swiper v-else class="join-box" circular :autoplay="true" :indicator-dots="true">
<swiper-item v-for="(item,index) in homeBanner" :key="index">
<image :src="item.bannerUrl" class="img" mode="aspectFill" :lazy-load="true"></image>
</swiper-item>
</swiper>
<!-- 快捷导航 -->
<view class="bg-white"
style="border-radius: 30rpx 30rpx 12rpx 12rpx;padding-top:8rpx;position: relative;margin-top:-20rpx">
<view class="search-box hover-effect" @click="toSearch">
<view class="search-input">
<text class="cuIcon-search" style="font-size: 40rpx;color: #A2A2A2;margin-right: 24rpx;"></text>
<text style="color: #A2A2A2;">搜索酒款名称品牌名称啤酒风格</text>
</view>
<view class="searchs">
<uni-icons type="search" size="30" color="#fff"></uni-icons>
</view>
</view>
<view class="flex justify-between bg-white" style="padding: 20rpx 36rpx;">
<view class="nav-item hover-effect" v-for="(item, index) in navItems" :key="index" @click="toGo(index + 1)">
<view class="flex justify-center align-center img-box">
<image :src="'/static/nav-' + (index + 1) + '.png'" style="width: 48rpx;height: 48rpx;" :lazy-load="true"></image>
</view>
<text class="text-bold">{{item}}</text>
</view>
</view>
</view>
<!-- <commonTitle title="热门活动招募"></commonTitle> -->
<view class="section-title">
<text>热门活动招募</text>
</view>
<!-- 活动列表容器 -->
<view class="list-container">
<scroll-view
scroll-y="true"
@scrolltolower="changePage"
:scroll-anchoring="true"
>
<view class="activity-list" style="margin-top: 16rpx;">
<activity-item
v-for="(item, index) in featurePageList"
:key="index"
:item="item"
@click="handleActivityClick"
@review="toReview"
/>
</view>
<view v-if="featurePageList.length > 0" class="more-btn-box" @click="moreHotActivity">
<view class="more-btn">更多热门活动招募</view>
</view>
</scroll-view>
</view>
<!-- <view class="weixin-box zixuns">
<text>入驻助理在线服务1对1咨询使用指南~</text>
<view class="btn" @click="toAddAiad">立即添加</view>
</view> -->
<!-- <view class="weixin-box zixuns">
<text>账户正在审核中请稍等~</text>
<view class="btn" @click="toAddAiad">立即添加</view>
</view> -->
<loginPopup ref="loginRef" @loginSuccess="loginSuccess"></loginPopup>
<!-- 开屏广告 -->
<uni-popup ref="ADRef" type="center" :is-mask-click="false" maskBackgroundColor="rgba(0,0,0,0.7)" @change="handlePopupChange">
<view class="ad-container">
<swiper class="ad-swiper"
:circular="false"
:autoplay="false"
:duration="300"
:indicator-dots="true"
:indicator-color="'rgba(255,255,255,0.3)'"
:indicator-active-color="'#FFFFFF'"
@change="handleAdSwiperChange">
<swiper-item v-for="(item,index) in ADList"
:key="index"
class="ad-swiper-item"
:class="{'active': currentAdIndex === index}"
@click="handleAD(item)">
<view class="ad-image-container">
<image :src="item.bannerUrl"
class="ad-image"
mode="aspectFill"
:lazy-load="true">
</image>
</view>
</swiper-item>
</swiper>
<view class="ad-close" @click="closeAd">
<text class="cuIcon-roundclose"></text>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import {
getBannerList,
getActivities
} from '@/api/bar.js'
import {
listFeaturePage
} from '@/api/platform.js'
import commonTitle from '@/components/commonTitle.vue'
import loginPopup from '@/components/loginPopup.vue';
import rowBeer from '@/components/rowBeer.vue'
import ActivityItem from '@/components/ActivityItem.vue'
export default {
components: {
commonTitle,
loginPopup,
rowBeer,
ActivityItem
},
data() {
return {
statusBaeHeight: 0,
curTag: 0,
ADList: [], // 广告弹窗
bannerJoin: null, // 认证门店banner
showJoinImg: false, // 是否显示认证门店图片
userInfo: null,
featurePageList: [], // 活动列表
homeBanner: [], //首页banner
keyword: '',
pageNum: 1,
pageSize: 10,
total: 0,
loading: false,
finished: false,
navItems: ['新酒上市', '生成酒单', '酒币换购', '关注厂牌'],
currentAdIndex: 0, // 当前广告索引
};
},
created() {
console.log('Index page created')
},
mounted() {
console.log('Index page mounted')
},
onReady() {
console.log('Index page ready')
// 确保数据已加载
if (this.featurePageList.length === 0) {
this.getActivityList()
}
},
watch: {
featurePageList: {
handler(newVal) {
console.log('featurePageList changed', newVal)
},
deep: true
}
},
onLoad() {
// setTimeout(() => {
// uni.setNavigationBarColor({
// frontColor: '#ffffff',
// backgroundColor: '#FFFFFF',
// animation: {
// duration: 400,
// timingFunc: 'easeIn'
// }
// })
// }, 500)
this.statusBaeHeight = uni.getWindowInfo.statusBarHeight
this.getBannerListFun() // 广告轮播图
uni.showShareMenu({
menus: ['shareAppMessage', 'shareTimeline']
})
// 禁用页面下拉刷新
uni.stopPullDownRefresh()
},
onShow() {
this.userInfo = uni.getStorageSync('userInfo')
if (this.userInfo == null || this.userInfo.userType == '09') {
this.showJoinImg = true
} else {
this.showJoinImg = false
}
// 重置分页参数
this.pageNum = 1
this.finished = false
this.featurePageList = []
this.getActivityList() // 获取活动列表
},
// onPullDownRefresh(){
// this.getFeaturePageListFun() // 专辑页列表
// },
onPullDownRefresh() {
// 禁用页面下拉刷新效果
uni.stopPullDownRefresh()
},
methods: {
loginSuccess() {
this.userInfo = uni.getStorageSync('userInfo')
if (this.userInfo == null || this.userInfo.userType == '09') { // 没登录或者没认证门店
console.log('登录')
this.showJoinImg = true
}else {
this.showJoinImg = false
}
},
toAddAiad() {
uni.navigateTo({
url: '/pagesMy/addAiad'
})
},
// 搜索
toSearch() {
uni.navigateTo({
url: '/pagesActivity/homeSearch',
success: () => {
uni.$emit('openKeyboard')
}
})
},
changeTag(index) {
this.curTag = index
},
// 查询广告弹窗 banner列表
getBannerListFun() {
this.ADList = []
this.homeBanner = []
this.bannerJoin = null
getBannerList().then(res => {
res.data.forEach(it => {
if (it.bannerType == 'homeAD') { // 开屏广告
this.ADList.push(it)
} else if (it.bannerType == 'homeJoin') { // 认证门店
this.bannerJoin = it
} else if (it.bannerType == 'homeBanner') { // 首页banner
this.homeBanner.push(it)
}
})
// 检查是否需要显示开屏广告
this.checkShowAD()
})
},
// 检查是否需要显示开屏广告
checkShowAD() {
if (this.ADList.length === 0) return
const currentSession = uni.getStorageSync('currentSession')
const newSession = Date.now()
// 每次打开小程序都显示广告
if (!currentSession || currentSession !== newSession) {
this.$refs.ADRef.open()
// 记录本次会话时间
uni.setStorageSync('currentSession', newSession)
}
},
// 关闭广告
closeAd() {
this.$refs.ADRef.close()
},
handleAD(item) {
this.closeAd()
if (item.bannerLink) {
uni.navigateTo({
url: item.bannerLink,
})
}
},
// 跳转专辑页
toFeaturePage(item) {
uni.navigateTo({
url: `/pages/index/featureInfo?id=${item.id}`
})
},
// 查询专辑页列表
getFeaturePageListFun() {
listFeaturePage().then(res => {
this.featurePageList = res.data
})
},
// 跳转酒评页
toReview(it) {
uni.navigateTo({
url: "/pages/index/review?beerId=" + it.id
})
},
toGo(key) {
switch (key) {
case 1: // 新酒上市
uni.navigateTo({
url: "/pages/index/newBeer"
})
break;
case 2: // 生成酒单
uni.navigateTo({
url: "/pagesActivity/winelist"
})
break;
case 3: //酒币换购
uni.navigateTo({
url: "/pagesCoin/beerCoin"
})
break;
case 4: // 关注酒厂
uni.navigateTo({
url: '/pagesMy/myAttention'
})
break;
}
},
// 更多热门活动
moreHotActivity() {
uni.navigateTo({
url: "/pages/activityList/activityList"
})
},
search() {
// 实现搜索逻辑
console.log('搜索关键词:', this.keyword);
},
changeSearch() {
// 实现搜索逻辑
console.log('搜索关键词:', this.keyword);
},
// 获取活动列表
async getActivityList() {
if (this.loading || this.finished) return
this.loading = true
try {
const res = await getActivities({
pageNum: this.pageNum,
pageSize: this.pageSize
})
if (res.code === 200) {
const { rows, total } = res
// 处理数据,计算剩余天数和状态
const processedRows = rows.map(it => {
// 计算剩余天数
const targetDate = new Date(it.endDate);
const currentDate = new Date();
const timeDiff = targetDate.getTime() - currentDate.getTime();
const remainingDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
// 设置活动状态
let activityState = 'recruiting';
if (it.activityStatus === 2) {
activityState = 'in_progress';
} else if (it.activityStatus === 3) {
activityState = 'completed';
}
return {
...it,
remainingDays,
activityState,
remainingBeerCount: it.remainingBeerCount || 0,
barAwardStatus: it.barAwardStatus || 0
};
});
// 过滤掉招募剩余天数为负数的活动
const filteredRows = processedRows.filter(item => {
if (item.activityState === 'recruiting') {
return item.remainingDays >= 0
}
return true
});
if (this.pageNum === 1) {
this.featurePageList = filteredRows;
} else {
this.featurePageList = [...this.featurePageList, ...filteredRows];
}
this.total = total;
this.finished = this.featurePageList.length >= total;
this.pageNum++;
}
} catch (error) {
console.error('获取活动列表失败:', error)
} finally {
this.loading = false
}
},
// 修改页面加载更多方法
async changePage() {
if (!this.finished) {
await this.getActivityList()
}
},
// 处理活动项点击
handleActivityClick(item) {
console.log('handleActivityClick called', item)
uni.navigateTo({
url: "/pagesActivity/activityDetail?id=" + item.id
})
},
handlePopupChange(e) {
if (e && e.detail) {
this.currentAdIndex = e.detail.current;
}
},
handleAdSwiperChange(e) {
if (e && e.detail) {
this.currentAdIndex = e.detail.current;
}
},
}
}
</script>
<style lang="scss" scoped>
/deep/.uni-popup {
z-index: 1025;
}
.page {
background: #F9F9F9;
min-height: 100vh;
display: flex;
flex-direction: column;
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", Roboto, "Segoe UI", "Microsoft YaHei", sans-serif;
}
.search-box {
border-radius: 24rpx;
width: 700rpx;
height: 80rpx;
background-color: #F9F9F9;
display: flex;
align-items: center;
padding: 32rpx 0;
margin: 26rpx auto;
box-sizing: border-box;
box-shadow: 0rpx 1rpx 3rpx 0rpx rgba(0, 0, 0, 0.1);
.search-input {
flex: 1;
display: flex;
align-items: center;
padding: 0 24rpx;
}
.searchs{
background: #D42E78;
width: 80rpx;
height: 80rpx;
border-radius: 0 24rpx 24rpx 0;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0rpx 1rpx 3rpx 0rpx rgba(0, 0, 0, 0.1);
}
}
.section-title {
margin: 46rpx 24rpx 32rpx 24rpx;
font-size: 40rpx;
font-weight: bold;
color: #030303;
}
.list-container {
flex: 1;
display: flex;
flex-direction: column;
scroll-view {
flex: 1;
}
.activity-list {
padding: 0 24rpx;
}
.more-btn-box {
width: 92%;
height: 88rpx;
margin: 32rpx auto;
background: linear-gradient(135deg, #19367A, #2C4C99);
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 16rpx rgba(25, 54, 122, 0.2);
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
box-shadow: 0 2rpx 8rpx rgba(25, 54, 122, 0.1);
}
.more-btn {
font-size: 28rpx;
font-weight: 600;
letter-spacing: 2rpx;
color: #FFFFFF;
}
}
}
.join-box {
// margin: 20rpx 0;
// border-radius: 30rpx;
box-sizing: border-box;
// border: 1.5px solid #F2F2F2;
// padding: 34rpx 26rpx;
// height: 450rpx;
// height: 1130rpx;
height: 562rpx;
display: flex;
flex-direction: column;
justify-content: space-around;
.btn {
width: 582rpx;
height: 68rpx;
border-radius: 24rpx;
text-align: center;
line-height: 68rpx;
margin: 0 auto;
background: #D42E78;
}
.img {
width: 100%;
height: 100%;
}
}
.swiper {
margin-bottom: 20rpx;
height: 400rpx;
}
// 快捷导航
.nav-item {
text-align: center;
color: #0B0E26;
.img-box {
width: 146rpx;
height: 146rpx;
background: #F9F9F9;
border-radius: 50%;
margin-bottom: 18rpx;
box-shadow: 0rpx 1rpx 3rpx 0rpx rgba(0, 0, 0, 0.1);
}
}
.quickNav-box {
border-radius: 20rpx;
background: #FFFFFF;
width: 100%;
padding: 32rpx 24rpx;
height: 490rpx;
box-sizing: border-box;
.left {
height: 416rpx;
width: 352rpx;
// width: 47%;
border-radius: 20rpx;
margin-right: 22rpx;
}
.right {
height: 196rpx;
// width: 326rpx;
width: 100%;
margin-bottom: 22rpx;
border-radius: 20rpx;
}
}
.goods-box {
border-radius: 30rpx;
background: rgba(255, 255, 255, 0.2);
box-sizing: border-box;
border: 1px solid #F2F2F2;
box-shadow: 0px 5.47px 43.78px 0px rgba(0, 0, 0, 0.05);
display: flex;
padding: 16rpx 32rpx;
margin: 20rpx 32rpx 0;
.cover {
width: 208rpx;
height: 300rpx;
border-radius: 30rpx;
margin-right: 14rpx;
}
}
.tag {
background-color: transparent;
border-radius: 12rpx;
padding: 12rpx 20rpx;
border: 1px solid #9D9D9D;
;
margin-right: 24rpx;
margin-bottom: 50rpx;
}
.active-tag {
background-color: #FEE034;
font-weight: bold;
border: 1px solid #FEE034;
}
.title-box {
padding: 24rpx 32rpx;
margin-bottom: 28rpx;
box-sizing: border-box;
.title {
font-size: 32rpx;
font-weight: bold;
color: #1E2019;
line-height: 130%;
}
.sub {
font-size: 20rpx;
color: #9D9D9D;
}
}
.zixuns {
padding: 0 34rpx 0 20rpx;
background: rgba(0, 0, 0, 0.6);
}
.bg-white {
background: #FFFFFF;
// box-shadow: 0rpx 1rpx 3rpx 0rpx rgba(0, 0, 0, 0.1);
}
.activity-item {
display: block;
}
.hover-effect {
transition: all 0.2s ease;
&:active {
transform: scale(0.96);
opacity: 0.8;
}
}
.search-box {
// ... existing code ...
&:active {
transform: scale(0.98);
opacity: 0.9;
}
}
.nav-item {
// ... existing code ...
&:active {
transform: scale(0.95);
opacity: 0.8;
}
}
.more-btn-box {
// ... existing code ...
&:active {
transform: scale(0.98);
opacity: 0.9;
}
}
.activity-item {
// ... existing code ...
&:active {
transform: scale(0.98);
opacity: 0.9;
}
}
// 添加图片加载优化相关样式
.img {
width: 100%;
height: 100%;
will-change: transform;
backface-visibility: hidden;
transform: translateZ(0);
}
// 添加骨架屏样式
.skeleton {
background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
background-size: 400% 100%;
animation: skeleton-loading 1.4s ease infinite;
}
@keyframes skeleton-loading {
0% {
background-position: 100% 50%;
}
100% {
background-position: 0 50%;
}
}
.ad-container {
position: relative;
width: 750rpx;
height: 70vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
animation: fadeIn 0.3s ease;
padding: 0 40rpx;
box-sizing: border-box;
}
.ad-swiper {
width: 100%;
height: 85%;
overflow: visible;
}
.ad-swiper-item {
box-sizing: border-box;
transition: all 0.3s ease;
transform: scale(0.85);
opacity: 0.6;
&.active {
transform: scale(1);
opacity: 1;
}
}
.ad-image-container {
width: 100%;
height: 100%;
position: relative;
border-radius: 30rpx;
overflow: hidden;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.15);
}
.ad-image {
width: 100%;
height: 100%;
border-radius: 30rpx;
will-change: transform;
backface-visibility: hidden;
transform: translateZ(0);
}
.ad-close {
margin-top: 40rpx;
width: 72rpx;
height: 72rpx;
display: flex;
justify-content: center;
align-items: center;
background: rgba(255, 255, 255, 0.15);
border-radius: 50%;
backdrop-filter: blur(10px);
transition: all 0.3s ease;
.cuIcon-roundclose {
font-size: 44rpx;
color: #FFFFFF;
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.2);
}
&:active {
transform: scale(0.9);
opacity: 0.8;
background: rgba(255, 255, 255, 0.25);
}
}
/deep/ .uni-swiper-dots {
bottom: -20rpx !important;
.uni-swiper-dot {
width: 12rpx !important;
height: 12rpx !important;
border-radius: 6rpx !important;
margin: 0 6rpx !important;
transition: all 0.3s ease !important;
background: rgba(255, 255, 255, 0.3) !important;
&.uni-swiper-dot-active {
width: 28rpx !important;
background-color: #FFFFFF !important;
box-shadow: 0 2rpx 8rpx rgba(255, 255, 255, 0.3);
}
}
}
</style>