1123 lines
26 KiB
Vue
1123 lines
26 KiB
Vue
<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>
|
||
|
||
<!-- 品牌广告图片 -->
|
||
<view class="banner-container">
|
||
<image class="banner" :src="breweryInfo.brandCover" mode="aspectFill"></image>
|
||
<view class="banner-overlay"></view>
|
||
</view>
|
||
|
||
<!-- 品牌信息卡片 -->
|
||
<view class="brand-header">
|
||
<view class="brand-info">
|
||
<view class="flex align-start justify-between">
|
||
<view class="flex align-center">
|
||
<image :src="breweryInfo.brandLogo" class="brand-logo" mode="aspectFill"></image>
|
||
<view class="flex flex-col">
|
||
<text class="brand-name">{{ breweryInfo.brandName}}</text>
|
||
<view class="brand-location">
|
||
<text class="cuIcon-location"></text>
|
||
<text>{{breweryInfo.country}}·{{breweryInfo.province}}·{{breweryInfo.city}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="action-buttons">
|
||
<view class="action-btn favor-btn" @click="favorBreweryFun(1)" v-if="!isFavor">
|
||
<image src="/static/heart-add.png" class="action-icon" mode="aspectFit"></image>
|
||
</view>
|
||
<view class="action-btn favor-btn active" @click="favorBreweryFun(2)" v-else>
|
||
<image src="/static/heart-tick.png" class="action-icon" mode="aspectFit"></image>
|
||
</view>
|
||
<view class="action-btn share-btn" @click="share">
|
||
<image src="/static/send.png" class="action-icon" mode="aspectFit"></image>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="brand-stats">
|
||
<view class="stat-item">
|
||
<text class="stat-value">{{ beerTotal}}</text>
|
||
<text class="stat-label">在售酒款</text>
|
||
</view>
|
||
<view class="stat-divider"></view>
|
||
<view class="stat-item">
|
||
<text class="stat-value">{{ breweryInfo.buildingDate && breweryInfo.buildingDate.substr(0,4)}}</text>
|
||
<text class="stat-label">since</text>
|
||
</view>
|
||
<view class="stat-divider"></view>
|
||
<view class="stat-item">
|
||
<text class="stat-value">{{myCoin || '--'}}</text>
|
||
<text class="stat-label">啤酒币</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="brand-desc-container">
|
||
<view class="brand-desc">{{breweryInfo.desc}}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 标签页导航 -->
|
||
<view class="tab-nav">
|
||
<view
|
||
class="tab-item"
|
||
:class="{'active':currentTab == 1}"
|
||
@click="changeTab(1)"
|
||
>
|
||
<text>在售酒款</text>
|
||
</view>
|
||
<view
|
||
class="tab-item"
|
||
:class="{'active':currentTab == 2}"
|
||
@click="changeTab(2)"
|
||
>
|
||
<text>累积活动</text>
|
||
</view>
|
||
<view
|
||
class="tab-item"
|
||
:class="{'active':currentTab == 3}"
|
||
@click="changeTab(3)"
|
||
>
|
||
<text>啤酒币兑换</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 内容区域 -->
|
||
<view class="content-box">
|
||
<!-- 在售酒款 -->
|
||
<view v-if="currentTab == 1" class="tab-content">
|
||
<scroll-view
|
||
scroll-y
|
||
enable-flex
|
||
class="scroll-container"
|
||
@scrolltolower="onScrollToLower"
|
||
>
|
||
<view class="beer-grid">
|
||
<beer-card
|
||
v-for="(item, index) in beerList"
|
||
:key="index"
|
||
:item="item"
|
||
@click="toReview(item)"
|
||
v-if="item && item.id"
|
||
></beer-card>
|
||
</view>
|
||
|
||
<view
|
||
class="loading-state"
|
||
:class="loading ? 'loading' : beerList.length >= beerTotal ? 'no-more' : ''"
|
||
v-if="beerList.length > 0"
|
||
>
|
||
<view v-if="loading" class="loading-text">
|
||
<text class="cuIcon-loading2 iconfont-spin"></text>
|
||
<text>加载中...</text>
|
||
</view>
|
||
<text v-else-if="beerList.length >= beerTotal" class="no-more-text">没有更多了</text>
|
||
</view>
|
||
|
||
<view class="empty-state" v-if="!loading && beerList.length === 0">
|
||
<image src="/static/empty.png" mode="aspectFit" class="empty-image"></image>
|
||
<text class="empty-text">暂无在售酒款</text>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
|
||
<!-- 累积活动 -->
|
||
<view v-if="currentTab == 2" class="tab-content">
|
||
<scroll-view
|
||
scroll-y
|
||
enable-flex
|
||
class="scroll-container"
|
||
@scrolltolower="onScrollToLower"
|
||
>
|
||
<!-- 空状态 -->
|
||
<view v-if="!loading && activityList.length === 0" class="empty-state">
|
||
<image src="/static/images/empty.png" class="empty-image" mode="aspectFit"></image>
|
||
<text class="empty-text">暂无活动</text>
|
||
</view>
|
||
|
||
<!-- 活动列表 -->
|
||
<view class="activity-list" v-else>
|
||
<activity-item
|
||
v-for="(item, index) in activityList"
|
||
:key="index"
|
||
:item="item"
|
||
@click="toActivityDetail"
|
||
@review="toReview"
|
||
></activity-item>
|
||
</view>
|
||
|
||
<!-- 加载状态 -->
|
||
<view
|
||
class="loading-state"
|
||
:class="loading ? 'loading' : activityList.length >= activityTotal ? 'no-more' : ''"
|
||
v-if="activityList.length > 0"
|
||
>
|
||
<view v-if="loading" class="loading-text">
|
||
<text class="cuIcon-loading2 iconfont-spin"></text>
|
||
<text>加载中...</text>
|
||
</view>
|
||
<text v-else-if="activityList.length >= activityTotal" class="no-more-text">没有更多了</text>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
|
||
<!-- 啤酒币兑换 -->
|
||
<view v-if="currentTab == 3" class="tab-content">
|
||
<scroll-view
|
||
scroll-y
|
||
enable-flex
|
||
class="scroll-container"
|
||
@scrolltolower="onScrollToLower"
|
||
>
|
||
<view class="goods-grid">
|
||
<view
|
||
class="goods-item"
|
||
v-for="(item, index) in goodsList"
|
||
:key="index"
|
||
@click="toDetail(item)"
|
||
>
|
||
<image class="goods-image" :src="item.goodsCover" mode="aspectFill"></image>
|
||
<view class="goods-info">
|
||
<view class="goods-title text-cut">{{item.goodsName}}</view>
|
||
<view class="goods-price">
|
||
<view class="price-left">
|
||
<text class="price-num">{{item.redeemedNum}}</text>
|
||
<text class="cuIcon-rechargefill coin-icon"></text>
|
||
</view>
|
||
<text class="brand-name">{{item.brandName}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view
|
||
class="loading-state"
|
||
:class="loading ? 'loading' : goodsList.length >= goodsTotal ? 'no-more' : ''"
|
||
v-if="goodsList.length > 0"
|
||
>
|
||
<view v-if="loading" class="loading-text">
|
||
<text class="cuIcon-loading2 iconfont-spin"></text>
|
||
<text>加载中...</text>
|
||
</view>
|
||
<text v-else-if="goodsList.length >= goodsTotal" class="no-more-text">没有更多了</text>
|
||
</view>
|
||
|
||
<view class="empty-state" v-if="!loading && goodsList.length === 0">
|
||
<image src="/static/empty.png" mode="aspectFit" class="empty-image"></image>
|
||
<text class="empty-text">暂无兑换商品</text>
|
||
</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';
|
||
import BeerCard from '@/components/BeerCard.vue';
|
||
export default {
|
||
components: {
|
||
loginPopup,
|
||
ActivityItem,
|
||
BeerCard
|
||
},
|
||
data() {
|
||
return {
|
||
statusBarHeight: 0, // 状态栏高度
|
||
showTabNav: false,
|
||
scrollTop: 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: 5,
|
||
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.beerList = []
|
||
this.getBreweryBeerListFun()
|
||
} else if (index == 2) {
|
||
this.activityList = []
|
||
this.getBreweryActivitiesFun()
|
||
} 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
|
||
})
|
||
this.activityList = [...this.activityList, ...arr]
|
||
}
|
||
}).catch(err => {
|
||
console.error('获取累积活动失败:', err)
|
||
uni.showToast({
|
||
title: err.msg || '获取活动列表失败,请稍后重试',
|
||
icon: 'none'
|
||
})
|
||
this.loading = false
|
||
})
|
||
},
|
||
// 在售酒款
|
||
getBreweryBeerListFun() {
|
||
this.loading = true
|
||
getBreweryBeerList(this.queryForm).then(res => {
|
||
this.loading = false
|
||
this.beerTotal = res.total
|
||
if (res.rows && res.rows.length > 0) {
|
||
this.beerList = [...this.beerList, ...res.rows.filter(item => item && item.id)]
|
||
}
|
||
}).catch(err => {
|
||
console.error('获取在售酒款失败:', err)
|
||
uni.showToast({
|
||
title: err.msg || '获取酒款列表失败,请稍后重试',
|
||
icon: 'none'
|
||
})
|
||
this.loading = false
|
||
})
|
||
},
|
||
// 兑换商品
|
||
getBreweryGoodsListFun() {
|
||
this.loading = true
|
||
getBreweryGoodsList(this.queryForm).then(res => {
|
||
this.loading = false
|
||
this.goodsTotal = res.total
|
||
if (res.rows && res.rows.length > 0) {
|
||
this.goodsList = [...this.goodsList, ...res.rows]
|
||
}
|
||
}).catch(err => {
|
||
console.error('获取兑换商品失败:', err)
|
||
uni.showToast({
|
||
title: err.msg || '获取商品列表失败,请稍后重试',
|
||
icon: 'none'
|
||
})
|
||
this.loading = false
|
||
})
|
||
},
|
||
// 滚动加载更多
|
||
onScrollToLower() {
|
||
if (this.loading) return
|
||
|
||
if (this.currentTab === 1 && this.activityList.length < this.activityTotal) {
|
||
this.queryForm.pageNum++
|
||
this.getBreweryActivitiesFun()
|
||
} else if (this.currentTab === 2 && this.beerList.length < this.beerTotal) {
|
||
this.queryForm.pageNum++
|
||
this.getBreweryBeerListFun()
|
||
} else if (this.currentTab === 3 && 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
|
||
})
|
||
},
|
||
onPageScroll(e) {
|
||
const tabNavThreshold = 300; // 设置一个阈值,当滚动超过这个值时显示导航
|
||
this.scrollTop = e.scrollTop;
|
||
this.showTabNav = this.scrollTop > tabNavThreshold;
|
||
},
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.page-content {
|
||
min-height: 100vh;
|
||
background-color: #F6F7FB;
|
||
position: relative;
|
||
|
||
/* 导航栏样式 */
|
||
.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.9);
|
||
border-radius: 50%;
|
||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
||
backdrop-filter: blur(10px);
|
||
-webkit-backdrop-filter: blur(10px);
|
||
|
||
.cuIcon-back {
|
||
font-size: 36rpx;
|
||
color: #333;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 品牌广告图片 */
|
||
.banner-container {
|
||
position: relative;
|
||
width: 100%;
|
||
height: 0;
|
||
padding-bottom: 75%; /* 4:3 比例 */
|
||
margin-top: v-bind('statusBarHeight + 44 + "px"');
|
||
overflow: hidden;
|
||
|
||
.banner {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
transition: transform 0.3s ease;
|
||
|
||
&:active {
|
||
transform: scale(1.02);
|
||
}
|
||
}
|
||
|
||
.banner-overlay {
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
height: 200rpx;
|
||
background: linear-gradient(to top, rgba(0,0,0,0.7), transparent);
|
||
}
|
||
}
|
||
|
||
/* 品牌信息卡片 */
|
||
.brand-header {
|
||
position: relative;
|
||
width: 100%;
|
||
margin-top: -150rpx;
|
||
z-index: 1;
|
||
|
||
.brand-info {
|
||
background-color: #fff;
|
||
border-radius: 42rpx 0rpx 0 0;
|
||
padding: 40rpx 32rpx;
|
||
box-shadow: 0 -10rpx 30rpx rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
.brand-logo {
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
margin-right: 24rpx;
|
||
border-radius: 50%;
|
||
object-fit: cover;
|
||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||
border: 4rpx solid #fff;
|
||
transition: transform 0.3s ease;
|
||
|
||
&:active {
|
||
transform: scale(1.05);
|
||
}
|
||
}
|
||
|
||
.brand-name {
|
||
color: #0B0E26;
|
||
font-size: 36rpx;
|
||
font-weight: 600;
|
||
margin-bottom: 12rpx;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.brand-location {
|
||
display: flex;
|
||
align-items: center;
|
||
color: #5E5F60;
|
||
font-size: 24rpx;
|
||
line-height: 1.4;
|
||
|
||
.cuIcon-location {
|
||
font-size: 24rpx;
|
||
margin-right: 8rpx;
|
||
color: #19367A;
|
||
}
|
||
}
|
||
|
||
.action-buttons {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
|
||
.action-btn {
|
||
width: 72rpx;
|
||
height: 72rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: #F5F5F5;
|
||
border-radius: 50%;
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
transform: scale(0.95);
|
||
}
|
||
|
||
&.active {
|
||
background: #19367A;
|
||
}
|
||
|
||
&.favor-btn {
|
||
&.active {
|
||
background: rgba(255, 77, 79, 0.1);
|
||
}
|
||
}
|
||
}
|
||
|
||
.action-icon {
|
||
width: 36rpx;
|
||
height: 36rpx;
|
||
}
|
||
}
|
||
|
||
.brand-stats {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin: 32rpx 0;
|
||
padding: 32rpx 0;
|
||
background: rgba(246, 247, 251, 0.5);
|
||
border-radius: 12rpx;
|
||
|
||
.stat-item {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
position: relative;
|
||
|
||
.stat-value {
|
||
font-size: 40rpx;
|
||
font-weight: 600;
|
||
color: #0B0E26;
|
||
margin-bottom: 12rpx;
|
||
line-height: 1.2;
|
||
}
|
||
|
||
.stat-label {
|
||
font-size: 24rpx;
|
||
color: #9C9BA6;
|
||
line-height: 1.4;
|
||
}
|
||
}
|
||
|
||
.stat-divider {
|
||
width: 2rpx;
|
||
height: 60rpx;
|
||
background: rgba(0, 0, 0, 0.05);
|
||
}
|
||
}
|
||
|
||
.brand-desc-container {
|
||
margin-left: 20rpx;
|
||
margin-right: 20rpx;
|
||
padding-top: 20rpx;
|
||
|
||
.brand-desc {
|
||
color: #666666;
|
||
font-size: 26rpx;
|
||
line-height: 1.8;
|
||
text-indent: 2em;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 标签页导航容器 */
|
||
.tab-nav-container {
|
||
position: relative;
|
||
background: #fff;
|
||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||
margin-bottom: 24rpx;
|
||
width: 100%;
|
||
}
|
||
|
||
/* 标签页导航 */
|
||
.tab-nav {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 0 24rpx;
|
||
background-color: #fff;
|
||
|
||
&:after {
|
||
content: '';
|
||
position: absolute;
|
||
// bottom: -16rpx;
|
||
left: 0;
|
||
right: 0;
|
||
height: 2rpx;
|
||
background: #FFF;
|
||
}
|
||
|
||
.tab-item {
|
||
flex: 1;
|
||
height: 80rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 28rpx;
|
||
font-weight: 500;
|
||
color: #666666;
|
||
position: relative;
|
||
transition: all 0.3s ease;
|
||
|
||
&.active {
|
||
color: #19367A;
|
||
font-weight: 600;
|
||
|
||
&:after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: -16rpx;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 40rpx;
|
||
height: 8rpx;
|
||
background: #19367A;
|
||
border-radius: 4rpx;
|
||
}
|
||
}
|
||
|
||
&:active {
|
||
opacity: 0.8;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 内容区域 */
|
||
.content-box {
|
||
margin-top: 32rpx;
|
||
box-sizing: border-box;
|
||
background-color: #fff;
|
||
border-radius: 24rpx;
|
||
box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.08);
|
||
|
||
/* 标签页内容区 */
|
||
.tab-content {
|
||
min-height: 600rpx;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* 滚动容器 */
|
||
.scroll-container {
|
||
width: 100%;
|
||
height: 100%;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* 活动列表容器 */
|
||
.activity-list {
|
||
width: 100%;
|
||
padding: 32rpx 32rpx;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
// border: 1rpx solid #FFD700;
|
||
}
|
||
|
||
/* 啤酒网格 */
|
||
.beer-grid {
|
||
width: 100%;
|
||
padding: 32rpx 32rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* 商品网格 */
|
||
.goods-grid {
|
||
width: 100%;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
padding: 32rpx 32rpx;
|
||
gap: 24rpx;
|
||
// padding: 0 24rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* 商品卡片 */
|
||
.goods-item {
|
||
width: calc((100% - 24rpx) / 2);
|
||
background: #FFFFFF;
|
||
border-radius: 12rpx;
|
||
overflow: hidden;
|
||
box-sizing: border-box;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
transform: scale(0.98);
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
|
||
}
|
||
|
||
.goods-image {
|
||
width: 100%;
|
||
height: 258rpx;
|
||
background: #F5F5F5;
|
||
transition: transform 0.3s ease;
|
||
|
||
&:active {
|
||
transform: scale(1.05);
|
||
}
|
||
}
|
||
|
||
.goods-info {
|
||
padding: 16rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.goods-title {
|
||
font-size: 24rpx;
|
||
color: #1A1A1A;
|
||
font-weight: 600;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
|
||
.goods-price {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
|
||
.price-left {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.price-num {
|
||
font-size: 32rpx;
|
||
color: #1A1A1A;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.coin-icon {
|
||
color: #FFD700;
|
||
font-size: 24rpx;
|
||
margin-left: 12rpx;
|
||
}
|
||
}
|
||
|
||
.brand-name {
|
||
font-size: 20rpx;
|
||
color: #808080;
|
||
background: #F6F7FB;
|
||
padding: 4rpx 12rpx;
|
||
border-radius: 20rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 加载状态 */
|
||
.loading-state {
|
||
width: 100%;
|
||
height: 100rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 20rpx 0;
|
||
|
||
&.loading {
|
||
.loading-text {
|
||
display: flex;
|
||
align-items: center;
|
||
color: #979797;
|
||
font-size: 24rpx;
|
||
|
||
.cuIcon-loading2 {
|
||
margin-right: 8rpx;
|
||
font-size: 28rpx;
|
||
filter: drop-shadow(0 1rpx 2rpx rgba(0, 0, 0, 0.1));
|
||
animation: loading-rotate 1s linear infinite;
|
||
}
|
||
}
|
||
}
|
||
|
||
&.no-more {
|
||
.no-more-text {
|
||
position: relative;
|
||
color: #979797;
|
||
font-size: 24rpx;
|
||
text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.05);
|
||
padding: 0 30rpx;
|
||
|
||
&::before,
|
||
&::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 50%;
|
||
width: 80rpx;
|
||
height: 1px;
|
||
background: linear-gradient(to right, transparent, #979797);
|
||
}
|
||
|
||
&::before {
|
||
left: -60rpx;
|
||
}
|
||
|
||
&::after {
|
||
right: -60rpx;
|
||
transform: rotate(180deg);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 空状态 */
|
||
.empty-state {
|
||
width: 100%;
|
||
height: 400rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.empty-image {
|
||
width: 200rpx;
|
||
height: 200rpx;
|
||
margin-bottom: 20rpx;
|
||
opacity: 0.8;
|
||
}
|
||
|
||
.empty-text {
|
||
color: #979797;
|
||
font-size: 28rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 文本截断 */
|
||
.text-cut {
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
/* 加载动画 */
|
||
.iconfont-spin {
|
||
animation: spin 1s linear infinite;
|
||
}
|
||
|
||
@keyframes spin {
|
||
from {
|
||
transform: rotate(0deg);
|
||
}
|
||
to {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
/* 加载动画 */
|
||
@keyframes loading-rotate {
|
||
from {
|
||
transform: rotate(0deg);
|
||
}
|
||
to {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
/* 上滑加载动画 */
|
||
@keyframes slide-in {
|
||
from {
|
||
transform: translateY(100%);
|
||
opacity: 0;
|
||
}
|
||
to {
|
||
transform: translateY(0);
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
/* 活动列表项动画 */
|
||
.activity-item {
|
||
animation: slide-in 0.3s ease-out;
|
||
}
|
||
|
||
/* 商品卡片动画 */
|
||
.goods-item {
|
||
animation: slide-in 0.3s ease-out;
|
||
}
|
||
|
||
/* 啤酒卡片动画 */
|
||
.beer-card {
|
||
animation: slide-in 0.3s ease-out;
|
||
}
|
||
</style> |