zdtap-uniapp-main/pages/index/brandHome.vue

687 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="page-content">
<!-- 自定义导航栏 -->
<view class="custom-nav" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="nav-content">
<view class="back-btn" @click="goBack">
<text class="cuIcon-back"></text>
</view>
</view>
</view>
<image class="banner" :src="breweryInfo.brandCover"></image>
<view class="brand-header">
<view style="padding:0 24rpx">
<view class="flex align-start justify-between margin-bottom-xl">
<view class="flex align-center">
<image :src="breweryInfo.brandLogo" style="width: 72rpx;height: 72rpx;margin-right: 36rpx;">
</image>
<view class="flex flex-col">
<text class="margin-bottom-xs"
style="color: #0B0E26;font-size: 32rpx;">{{ breweryInfo.brandName}}</text>
<text class=""
style="color: #5E5F60;font-size: 24rpx;">{{breweryInfo.country}}·{{breweryInfo.province}}·{{breweryInfo.city}}</text>
</view>
</view>
<view class="flex align-center">
<text v-if="!isFavor" class="cuIcon-like"
style="font-size: 50rpx;color: #0B0E26;margin-right: 30rpx;"
@click="favorBreweryFun(1)"></text>
<text v-else class="cuIcon-likefill" style="font-size: 50rpx;color: pink;margin-right: 30rpx;"
@click="favorBreweryFun(2)"></text>
<image src="/static/send.png" style="width: 50rpx;height: 50rpx;" @click="share"></image>
</view>
</view>
<view class="flex justify-between align-center">
<view style="width: 226rpx;text-align: center;">
<view class="margin-bottom-xs" style="font-size: 36rpx;">{{ beerTotal}}</view>
<view style="font-size: 24rpx;">在售酒款</view>
</view>
<view class="solid-left solid-right" style="width: 226rpx;text-align: center;">
<view class="margin-bottom-xs" style="font-size: 36rpx;">
{{ breweryInfo.buildingDate && breweryInfo.buildingDate.substr(0,4)}}
</view>
<view style="font-size: 24rpx;">since</view>
</view>
<view style="width: 226rpx;text-align: center;">
<view class="margin-bottom-xs" style="font-size: 36rpx;">{{myCoin || '--'}}</view>
<view style="font-size: 24rpx;">啤酒币</view>
</view>
</view>
</view>
<view style="color: #A1A1A1;font-size: 24rpx;margin-top:28rpx;text-indent: 2em;">
{{breweryInfo.desc}}
</view>
</view>
<view class="content-box">
<view class="top flex align-center justify-between">
<view class="def-box" :class="{'active':currentTab == 1}" @click="changeTab(1)">累积活动</view>
<view class="def-box" :class="{'active':currentTab == 2}" @click="changeTab(2)">在售酒款</view>
<view class="def-box" :class="{'active':currentTab == 3}" @click="changeTab(3)">啤酒币兑换</view>
</view>
<!-- 累积活动 -->
<view v-if="currentTab == 1">
<scroll-view scroll-y enable-flex class="scroll-container" @scrolltolower="changeActPage">
<activity-item
v-for="(item, index) in activityList"
:key="index"
:item="item"
@click="toActivityDetail"
@review="toReview"
></activity-item>
<view class="cu-load" style="width: 100%;"
:class="loading?'loading': activityList.length == activityTotal ? 'over' :'more'"></view>
</scroll-view>
</view>
<!-- 在售酒款 -->
<view v-if="currentTab == 2" class="">
<scroll-view scroll-y enable-flex class="scroll-container flex justify-start flex-wrap" @scrolltolower="changeBeerPage">
<view class="beer-box" v-for="(it, index) in beerList" :key="index" @click="toReview(it)">
<image :src="it.cover" class="cover"></image>
<view class="title word-all">{{ it.beerName}}</view>
<view class="desc word-all">{{ it.beerStyles }}</view>
<view class="desc word-all">{{ it.brandName }}</view>
<view class="flex align-center num">
<image src="@/static/vector.png" style="width: 20rpx;height: 20rpx;margin-right: 10rpx;">
</image>
{{ it.beerOverallRating || 0 }}{{ it.beerReviewsCount || 0}}
</view>
</view>
<view class="cu-load" style="width: 100%;"
:class="loading?'loading': beerList.length == beerTotal ? 'over' :'more'"></view>
</scroll-view>
</view>
<!-- 啤酒币兑换 -->
<view v-if="currentTab == 3" class="goods-container">
<scroll-view scroll-y enable-flex class="flex justify-start flex-wrap" style="height: 100%;"
lower-threshold="20" @scrolltolower="changeGoodsPage">
<view class="goods-item" v-for="(item, index) in goodsList" :key="index" @click="toDetail(item)">
<view class="cover-box">
<image :src="item.goodsCover" class="cover"></image>
<!-- <view class="like">
<text v-if="index % 2 == 0" class="cuIcon-like" style="color: #1E2019"></text>
<text v-else class="cuIcon-likefill" style="color: pink"></text>
</view> -->
</view>
<view class="title">
<text>{{ item.goodsName }}</text>
</view>
<view class="flex justify-between align-center" style="padding:26rpx 16rpx">
<view class="flex align-center">
<text class="num">{{ item.redeemedNum}}</text>
<image src="@/static/beerCoin.png"
style="width: 30rpx;height: 30rpx;margin-left: 20rpx;">
</image>
</view>
<!-- <text style="color: #979797;font-size: 20rpx;">青岛啤酒</text> -->
</view>
</view>
<view class="cu-load" style="width: 100%;"
:class="loading?'loading': goodsList.length == goodsTotal ? 'over' :'more'"></view>
</scroll-view>
</view>
</view>
<!-- 登录弹窗组件 -->
<loginPopup ref="loginRef" @loginSuccess="loginSuccess"></loginPopup>
</view>
</template>
<script>
import {
getBreweryInfo,
getBreweryActivities,
getBreweryBeerList,
getBreweryGoodsList,
favorBrewery,
getBreweryFavorStatus,
getBreweryCoinBalance
} from '@/api/bar.js'
import loginPopup from '@/components/loginPopup.vue';
import ActivityItem from '@/components/ActivityItem.vue';
export default {
components: {
loginPopup,
ActivityItem
},
data() {
return {
statusBarHeight: 0, // 状态栏高度
breweryId: '',
currentTab: 1,
breweryInfo: {}, // 品牌方详情
activityList: [],
goodsList: [],
beerList: [],
loading: false,
beerTotal: 0, // 在售酒款总数
goodsTotal: 0, // 兑换商品总数
activityTotal: 0, // 活动总数
total: 0,
formattedDate: '', // 当前年月日
isFavor: false, // 是否收藏
myCoin: 0, // 我的啤酒币
queryForm: {
pageNum: 1,
pageSize: 4,
id: ''
}
};
},
onLoad({
breweryId
}) {
// 获取状态栏高度
this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight
this.breweryId = breweryId
this.queryForm.id = breweryId
this.getBreweryInfoFun()
this.getBreweryActivitiesFun()
this.getBreweryBeerListFun()
this.getBreweryGoodsListFun()
this.getDate()
this.getBreweryFavorStatusFun()
this.getBreweryCoinBalanceFun() // 啤酒币余额
},
methods: {
// 返回上一页
goBack() {
uni.navigateBack()
},
changeTab(index) {
this.currentTab = index
this.queryForm.pageNum = 1
if (index == 1) {
this.activityList = []
this.getBreweryActivitiesFun()
} else if (index == 2) {
this.beerList = []
this.getBreweryBeerListFun()
} else if (index == 3) {
this.goodsList = []
this.getBreweryGoodsListFun()
}
},
// 登录成功回调
loginSuccess() {
this.getBreweryFavorStatusFun()
this.getBreweryCoinBalanceFun()
},
share() {
uni.downloadFile({
url: this.breweryInfo.brandCover,
success: (res) => {
console.log(res)
// #ifdef MP-WEIXIN
uni.showShareImageMenu({
provider: 'weixin',
// path: '/pages/index/featureInfo?id=' + this.id,
path: res.tempFilePath,
shareType: 0,
success: (res) => {
console.log(res)
},
fail: (err) => {
console.log(err)
}
})
// #endif
}
})
},
// 啤酒币余额
getBreweryCoinBalanceFun() {
getBreweryCoinBalance(this.breweryId).then(res => {
if (res.data) {
this.myCoin = res.data.balance || 0
} else {
this.myCoin = 0
}
}).catch(err => {
console.error('获取啤酒币余额失败:', err)
this.myCoin = 0
})
},
// 收藏品牌方状态
getBreweryFavorStatusFun() {
getBreweryFavorStatus(this.breweryId).then(res => {
if (res.data) {
this.isFavor = true
} else {
this.isFavor = false
}
}).catch(err => {
console.error('获取收藏状态失败:', err)
uni.showToast({
title: err.msg || '获取收藏状态失败,请稍后重试',
icon: 'none'
})
})
},
// 获取当前年月日
getDate() {
const currentDate = new Date();
// 获取年份
const year = currentDate.getFullYear();
// 获取月份(注意:月份是从 0 开始计数的,所以要加 1
const month = String(currentDate.getMonth() + 1).padStart(2, '0');
// 获取日期
const day = String(currentDate.getDate()).padStart(2, '0');
// 格式化日期为 YYYY-MM-DD 格式
this.formattedDate = `${year}-${month}-${day}`;
},
// 计算剩余天数
getRemainingDays(date) {
const targetDate = new Date(date);
const currentDate = new Date();
const timeDiff = targetDate.getTime() - currentDate.getTime();
const remainingDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
return remainingDays;
},
// 品牌方详情
getBreweryInfoFun() {
getBreweryInfo(this.breweryId).then(res => {
this.breweryInfo = res.data
}).catch(err => {
console.error('获取品牌方详情失败:', err)
uni.showToast({
title: err.msg || '获取品牌方详情失败,请稍后重试',
icon: 'none'
})
})
},
// 累积活动
getBreweryActivitiesFun() {
this.loading = true
getBreweryActivities(this.queryForm).then(res => {
this.loading = false
this.activityTotal = res.total
if (res.rows && res.rows.length > 0) {
let arr = res.rows.map(it => {
it.remainingDays = this.getRemainingDays(it.endDate)
return it
})
arr.forEach(it => {
this.activityList.push(it)
})
}
}).catch(err => {
console.error('获取累积活动失败:', err)
uni.showToast({
title: err.msg || '获取活动列表失败,请稍后重试',
icon: 'none'
})
this.loading = false
})
},
changeActPage() {
if (this.activityList.length < this.activityTotal) {
this.queryForm.pageNum++
this.getBreweryActivitiesFun()
}
},
// 在售酒款
getBreweryBeerListFun() {
this.loading = true
getBreweryBeerList(this.queryForm).then(res => {
this.loading = false
this.beerTotal = res.total
if (res.rows && res.rows.length > 0) {
res.rows.forEach(it => {
this.beerList.push(it)
})
}
}).catch(err => {
console.error('获取在售酒款失败:', err)
uni.showToast({
title: err.msg || '获取酒款列表失败,请稍后重试',
icon: 'none'
})
this.loading = false
})
},
changeBeerPage() {
if (this.beerList.length < this.beerTotal) {
this.queryForm.pageNum++
this.getBreweryBeerListFun()
}
},
// 兑换商品
getBreweryGoodsListFun() {
this.loading = true
getBreweryGoodsList(this.queryForm).then(res => {
this.loading = false
this.goodsTotal = res.total
if (res.rows && res.rows.length > 0) {
res.rows.forEach(it => {
this.goodsList.push(it)
})
}
}).catch(err => {
console.error('获取兑换商品失败:', err)
uni.showToast({
title: err.msg || '获取商品列表失败,请稍后重试',
icon: 'none'
})
this.loading = false
})
},
changeGoodsPage() {
if (this.goodsList.length < this.goodsTotal) {
this.queryForm.pageNum++
this.getBreweryGoodsListFun()
}
},
// 收藏品牌方
favorBreweryFun(status) {
const token = uni.getStorageSync('token')
if (!token) {
this.$refs.loginRef.open()
return
}
// 检查认证状态
const barInfo = uni.getStorageSync('barInfo')
if (!barInfo) {
uni.showModal({
title: '提示',
content: '请先认证门店',
showCancel: true,
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: '/pages/index/registration'
})
}
}
})
return
}
// 处理不同的认证状态
if (barInfo.authState === 0) {
uni.showModal({
title: '提示',
content: '请先认证门店',
showCancel: true,
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: '/pages/index/registration'
})
}
}
})
return
} else if (barInfo.authState === 2) {
uni.showToast({
title: '您的门店正在认证中,请耐心等待',
icon: 'none'
})
return
}
let data = {
breweryId: this.breweryId,
status
}
favorBrewery(data).then(res => {
if (status == 1) {
this.isFavor = true
uni.showToast({
title: '收藏成功',
icon: 'success'
})
} else {
this.isFavor = false
uni.showToast({
title: '取消收藏',
icon: 'none'
})
}
}).catch(err => {
if (err.code === 500 && err.msg.includes('门店未认证')) {
uni.showModal({
title: '提示',
content: '请先认证门店',
showCancel: true,
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: '/pages/index/registration'
})
}
}
})
} else {
uni.showToast({
title: err.msg || '操作失败',
icon: 'none'
})
}
})
},
// 跳转详情
toDetail(item) {
uni.navigateTo({
url: "/pagesCoin/goodsDetail?id=" + item.id + "&breweryId=" + item.breweryId
})
},
// 跳转活动详情
toActivityDetail(item) {
uni.navigateTo({
url: "/pagesActivity/activityDetail?id=" + item.id
})
},
// 跳转酒评
toReview(it) {
const token = uni.getStorageSync('token')
if (!token) {
this.$refs.loginRef.open()
return
}
uni.navigateTo({
url: "/pages/index/review?beerId=" + it.id
})
},
},
}
</script>
<style lang="scss" scoped>
.page-content {
.custom-nav {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
background: transparent;
.nav-content {
height: 44px;
display: flex;
align-items: center;
padding: 0 32rpx;
.back-btn {
width: 64rpx;
height: 64rpx;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.8);
border-radius: 50%;
.cuIcon-back {
font-size: 36rpx;
color: #000;
}
}
}
}
.banner {
width: 100%;
height: 724rpx;
margin-top: v-bind('statusBarHeight + 44 + "px"');
}
.brand-header {
position: relative;
width: 100%;
height: 100%;
padding: 20rpx 32rpx;
box-sizing: border-box;
background-color: #fff;
border-radius: 30rpx;
margin-top: -150rpx;
margin-bottom: 20rpx;
z-index: 1;
}
.content-box {
padding: 22rpx 26rpx;
box-sizing: border-box;
background-color: #fff;
border-radius: 30rpx;
.top {
padding: 0 72rpx;
margin-bottom: 20rpx;
.def-box {
font-size: 20rpx;
font-weight: 500;
color: #0B0E26;
width: 146rpx;
height: 52rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 13rpx;
background-color: #F2F2F2;
}
.active {
background: #39E5B1;
}
}
// 累积活动
.scroll-container {
margin-bottom: 50rpx;
padding: 0 24rpx;
}
// 在售酒款
.scroll-container {
margin-bottom: 50rpx;
justify-content: flex-start;
.beer-box {
width: 208rpx;
background: #FFFFFF;
margin-right: 12rpx;
margin-left: 12rpx;
margin-bottom: 36rpx;
box-sizing: border-box;
// display: inline-block;
min-height: 490rpx;
// &:nth-child(1) {
// margin-left: 32rpx;
// }
.cover {
width: 208rpx;
height: 300rpx;
border-radius: 30rpx;
margin-bottom: 18rpx;
}
.title {
font-size: 28rpx;
color: #1E2019;
margin-bottom: 12rpx;
color: #19191B;
}
.desc {
font-size: 24rpx;
color: #A5A7B9;
margin-bottom: 12rpx;
color: #979797;
}
.num {
font-size: 20rpx;
color: #5F5F63;
}
}
}
// 兑换商品
.goods-container {
flex: 1;
overflow-y: auto;
padding-bottom: calc(60rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(60rpx + env(safe-area-inset-bottom));
.goods-item {
width: 334rpx;
height: 605rpx;
border-radius: 30rpx;
background: rgba(255, 255, 255, 0.59);
box-sizing: border-box;
border: 1px solid rgba(242, 242, 242, 0.702);
margin-right: 20rpx;
margin-bottom: 56rpx;
&:nth-child(2n) {
margin-right: 0;
}
.cover-box {
width: 334rpx;
height: 440rpx;
border-radius: 30rpx 30rpx 0 0;
position: relative;
.cover {
width: 100%;
height: 100%;
border-radius: 30rpx 30rpx 0 0;
}
.like {
position: absolute;
right: 16rpx;
bottom: 18rpx;
width: 48rpx;
height: 48rpx;
border-radius: 50%;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
}
}
.title {
padding: 16rpx 14rpx;
font-size: 24rpx;
color: #3D3D3D;
}
}
}
}
}
</style>