zdtap-uniapp-main/pagesMy/myAttention.vue

493 lines
12 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">
<scroll-view scroll-x class="bg-white nav">
<view class="flex text-center">
<view class="cu-item flex-sub tab" :class="tabCur == 0?'active cur':''" @tap="tabSelect" :data-id="0">
酒款
</view>
<view class="cu-item flex-sub tab" :class="tabCur == 1?'active cur':''" @tap="tabSelect" :data-id="1">
品牌
</view>
</view>
</scroll-view>
<view v-if="!isLogin" class="flex align-center justify-center" style="height: calc(100vh - 100rpx);">
<view class="flex flex-col align-center">
<text style="color: #747783;font-size: 28rpx;margin-bottom: 30rpx;">登录后查看我的关注</text>
<button class="cu-btn" style="color: #FFFFFF; background-color: #4E63E0;" @click="toLogin">去登录</button>
</view>
</view>
<template v-else>
<view v-if="!isVerified && !isVerifying" class="flex align-center justify-center" style="height: calc(100vh - 100rpx);">
<view class="flex flex-col align-center">
<text style="color: #747783;font-size: 28rpx;margin-bottom: 30rpx;">请先完成门店认证</text>
<button class="cu-btn" style="color: #FFFFFF; background-color: #4E63E0;" @click="toVerify">去认证</button>
</view>
</view>
<view v-else-if="isVerifying" class="flex align-center justify-center" style="height: calc(100vh - 100rpx);">
<view class="flex flex-col align-center">
<text style="color: #747783;font-size: 28rpx;margin-bottom: 30rpx;">您的门店正在认证中请耐心等待</text>
</view>
</view>
<template v-else>
<view v-if="tabCur == 0" class="my-container">
<template v-if="favoriteBeerList.length > 0">
<scroll-view style="height: 100%;" enable-flex scroll-y @scrolltolower="changeBeerPage">
<view class="beer-grid">
<view class="beer-box" v-for="(item, index) in favoriteBeerList" :key="index" @click="toBeer(item)">
<view class="cover-box">
<image :src="item.cover" class="cover" mode="aspectFill"></image>
<view class="like">
<text class="cuIcon-likefill" style="color: #4E63E0"
@click.stop="cancelFavBeer(item)"></text>
</view>
</view>
<view class="info-box">
<view class="title">{{ item.beerName }}</view>
<view class="rating">
<text class="score">{{ item.beerOverallRating || '5' }}</text>
<text class="reviews">({{ item.beerReviewsCount || '0' }})</text>
</view>
</view>
</view>
</view>
<view class="cu-load" :class="favoriteBeerList.length == totalBeer ? 'over' :'more'"></view>
</scroll-view>
</template>
<template v-else>
<view class="flex align-center justify-center"
style="height: 140rpx;width: 100%;color: #747783;font-size: 24rpx;">暂无关注的酒款</view>
</template>
</view>
<view v-if="tabCur == 1" class="my-brandSide">
<template v-if="favoriteBreweryList.length > 0">
<scroll-view style="height: 100%;" scroll-y="true" @scrolltolower="changeBreweryPage">
<view class="brandSide-box" v-for="(item, index) in favoriteBreweryList" :key="index"
@click="toBrand(item)">
<view class="flex align-center justify-start">
<image :src="item.brandLogo" class="logo"></image>
<view>
<view class="title">{{ item.brandName }}</view>
</view>
</view>
<view class="cu-btn radius bg-gray" @click.stop="cancelFavBrewery(item)">取消关注</view>
</view>
</scroll-view>
</template>
<template v-else>
<view class="flex align-center justify-center"
style="height: 140rpx;width: 100%;color: #747783;font-size: 24rpx;">暂无关注的品牌</view>
</template>
</view>
</template>
</template>
<loginPopup ref="loginRef" @loginSuccess="loginSuccess"></loginPopup>
</view>
</template>
<script>
import {
listMyFavoriteBeer,
listMyFavoriteBrewery
} from '@/api/user.js'
import {
favorBeer,
favorBrewery
} from '@/api/bar.js'
import loginPopup from '@/components/loginPopup.vue'
export default {
components: {
loginPopup
},
data() {
return {
isLogin: false,
isVerified: false,
isVerifying: false,
tabCur: 0,
favoriteBeerList: [], // 收藏的酒款列表
favoriteBreweryList: [], // 收藏的酒厂列表
beerQuery: {
pageNum: 1,
pageSize: 10
},
breweryQuery: {
pageNum: 1,
pageSize: 10
},
totalBeer: 0,
totalBrewery: 0
};
},
onShow() {
this.checkLoginStatus()
},
onLoad() {
// 监听需要登录的事件
uni.$on('needLogin', () => {
this.toLogin()
})
},
onUnload() {
// 移除事件监听
uni.$off('needLogin')
},
methods: {
// 检查登录状态
checkLoginStatus() {
const token = uni.getStorageSync('token')
const userInfo = uni.getStorageSync('userInfo')
const barInfo = uni.getStorageSync('barInfo')
// 重置状态
this.isLogin = false
this.isVerified = false
this.isVerifying = false
this.favoriteBeerList = []
this.favoriteBreweryList = []
this.beerQuery.pageNum = 1
this.breweryQuery.pageNum = 1
// 检查登录状态
if (!token) {
return
}
this.isLogin = true
// 检查认证状态
if (barInfo) {
if (barInfo.authState === 2) {
// 已认证
this.isVerified = true
this.isVerifying = false
} else if (barInfo.authState === 1) {
// 认证中
this.isVerified = false
this.isVerifying = true
} else {
// 未认证
this.isVerified = false
this.isVerifying = false
}
} else {
// 兼容旧版本使用userInfo中的isVerified
this.isVerified = userInfo?.isVerified === 1
this.isVerifying = false
}
// 如果已登录且已认证或正在认证中,获取关注列表
if (this.isVerified || this.isVerifying) {
this.getFavoriteBeerList()
this.getFavoriteBreweryList()
}
},
// 去登录
toLogin() {
this.$refs.loginRef.open()
},
// 去认证
toVerify() {
uni.navigateTo({
url: '/pages/index/registration'
})
},
// 登录成功
loginSuccess() {
// 重新检查登录状态
this.checkLoginStatus()
},
tabSelect(e) {
console.log(e)
this.tabCur = e.currentTarget.dataset.id;
// if(this.tabCur == 0) {
// this.favoriteBeerList = []
// this.beerQuery.pageNum = 1
// this.getFavoriteBeerList()
// } else {
// this.favoriteBreweryList = []
// this.breweryQuery.pageNum = 1
// this.getFavoriteBreweryList()
// }
},
// 获取收藏的酒款列表
getFavoriteBeerList() {
if (!this.isLogin) return
listMyFavoriteBeer(this.beerQuery).then(res => {
this.totalBeer = res.total
if (res.rows && res.rows.length > 0) {
res.rows.forEach(it => {
this.favoriteBeerList.push(it)
})
}
}).catch(() => {
// 出错时不显示错误提示,因为已经在请求拦截器中处理了
})
},
// 酒款翻页
changeBeerPage() {
console.log('f1')
if (this.favoriteBeerList.length < this.totalBeer) {
this.beerQuery.pageNum++
this.getFavoriteBeerList()
}
},
// 获取收藏的酒厂列表
getFavoriteBreweryList() {
if (!this.isLogin) return
listMyFavoriteBrewery(this.breweryQuery).then(res => {
this.totalBrewery = res.total
if (res.rows && res.rows.length > 0) {
res.rows.forEach(it => {
this.favoriteBreweryList.push(it)
})
}
}).catch(() => {
// 出错时不显示错误提示,因为已经在请求拦截器中处理了
})
},
// 品牌方翻页
changeBreweryPage() {
console.log('f')
if (this.favoriteBreweryList.length < this.totalBrewery) {
this.breweryQuery.pageNum++
this.getFavoriteBreweryList()
}
},
// 跳转到酒款详情
toBeer(item) {
uni.navigateTo({
url: "/pages/index/review?beerId=" + item.beerId
})
},
// 跳转到品牌详情
toBrand(item) {
uni.navigateTo({
url: '/pages/index/brandHome?breweryId=' + item.breweryId
})
},
// 取消关注酒款
cancelFavBeer(item) {
if (!this.isLogin) {
this.toLogin()
return
}
let data = {
beerId: item.beerId,
status: 2
}
favorBeer(data).then(res => {
uni.showToast({
title: '取消收藏',
icon: 'none'
})
this.favoriteBeerList = []
this.beerQuery.pageNum = 1
this.getFavoriteBeerList()
}).catch(() => {
// 出错时不显示错误提示,因为已经在请求拦截器中处理了
})
},
// 取消关注酒厂
cancelFavBrewery(item) {
if (!this.isLogin) {
this.toLogin()
return
}
let data = {
breweryId: item.breweryId,
status: 2
}
favorBrewery(data).then(res => {
uni.showToast({
title: '取消收藏',
icon: 'none'
})
this.favoriteBreweryList = []
this.breweryQuery.pageNum = 1
this.getFavoriteBreweryList()
}).catch(() => {
// 出错时不显示错误提示,因为已经在请求拦截器中处理了
})
},
}
}
</script>
<style lang="scss" scoped>
.page-content {
background: #F9F9F9;
height: 100vh;
.nav {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
padding: 0 32rpx;
background: #FFFFFF;
height: 88rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
.tab {
position: relative;
width: calc((100% - 56rpx) / 2); // 两等分宽度(减去间距)
margin: 0 14rpx; // 统一的间距
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
color: #1A1A1A;
font-weight: normal;
transition: all 0.3s ease;
&.active {
color: #4E63E0;
font-weight: 600;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 48rpx;
height: 4rpx;
background: #4E63E0;
border-radius: 2rpx;
}
}
}
}
.my-container {
padding: 28rpx 36rpx;
margin-top: 88rpx; // 为固定定位的导航栏留出空间
height: calc(100vh - 88rpx);
.beer-grid {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
margin: -14rpx; // 抵消子元素的margin
.beer-box {
width: calc((100% - 84rpx) / 3); // 三等分宽度(减去两个间距)
margin: 14rpx; // 统一的间距
background: #FFFFFF;
box-sizing: border-box;
display: flex;
flex-direction: column;
border-radius: 16rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
overflow: hidden;
.cover-box {
width: 100%;
padding-bottom: 144%; // 保持图片比例
position: relative;
overflow: hidden;
.cover {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.like {
position: absolute;
right: 16rpx;
bottom: 18rpx;
width: 48rpx;
height: 48rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(4rpx);
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
display: flex;
justify-content: center;
align-items: center;
}
}
.info-box {
padding: 12rpx;
.title {
font-size: 28rpx;
color: #19191B;
font-weight: 600;
margin-bottom: 8rpx;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.rating {
display: flex;
align-items: center;
font-size: 24rpx;
.score {
color: #FFA033;
font-weight: 600;
margin-right: 4rpx;
}
.reviews {
color: #999999;
font-size: 20rpx;
}
}
}
}
}
}
.my-brandSide {
padding: 28rpx 36rpx;
height: calc(100vh - 100rpx);
.brandSide-box {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 0;
border-bottom: 1rpx solid #F0F4F9;
padding: 32rpx 0;
.logo {
width: 108rpx;
height: 108rpx;
border-radius: 50%;
margin-right: 28rpx;
}
.title {
font-size: 28rpx;
color: #19191B;
margin-bottom: 20rpx;
}
.desc {
font-size: 20rpx;
color: #9C9BA6;
}
}
}
}
</style>