web-zk-h5/pages/shareArea/hiList.vue

1516 lines
36 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="contain">
<view class="tab-container">
<view class="tab-wrapper">
<view
v-for="tab in tabs"
:key="tab.value"
class="tab-item"
:class="{ 'tab-active': activeTab === tab.value }"
@click="switchTab(tab.value)"
>
<text class="tab-text">{{ tab.label }}</text>
<view class="tab-line" v-if="activeTab === tab.value"></view>
</view>
</view>
</view>
<!-- 分类和搜索区域 - 仅在北大甄选时显示 -->
<view class="category-container" v-if="activeTab === 43">
<view class="category-section">
<view class="category-left">
<view
v-for="item in oneList"
:class="[
'category-item',
oneId == item.pkId ? 'category-active' : '',
]"
@click="selectOneCategory(item)"
:key="item.pkId"
>
{{ item.classifyName }}
</view>
</view>
<view class="category-right">
<!-- 二级分类 -->
<scroll-view
class="category-scroll"
scroll-x="true"
:show-scrollbar="false"
v-if="twoList.length > 0"
>
<view class="category-tabs">
<view
v-for="(item, index) in twoList"
:key="index"
@click="selectTwoCategory(item)"
:class="[twoId == item.pkId ? 'tab-active' : 'tab-item']"
>
{{ item.classifyName }}
</view>
</view>
</scroll-view>
<!-- 搜索框 -->
<view class="search-container">
<view class="search-input-wrapper">
<u--input
class="search-input"
placeholder="请输入商品名称"
placeholderStyle="font-size:14px;"
prefixIcon="search"
shape="circle"
v-model="waresName"
border="none"
prefixIconStyle="font-size: 22px;color: #909399"
@confirm="searchGoods"
/>
</view>
</view>
<!-- 北大甄选的商品列表 -->
<view class="goods-list-container">
<scroll-view
class="goodList"
scroll-y="true"
enhanced
:show-scrollbar="false"
>
<view
v-for="item in goodList"
:key="item.waresCode"
class="goodList_i"
>
<img :src="item.cover1" class="cover" alt="" />
<view class="goodList_ir">
<view class="tit1">
{{ item.waresName }}
</view>
<view class="goodList_ib">
<view class="price-container">
<!-- <text class="currency">¥</text> -->
<text class="price">{{
formatCurrency(item.waresPrice)
}}</text>
<text v-if="item.isSale === 1" class="sale-status"
>已售罄</text
>
</view>
</view>
<!-- 加入购物车按钮区域 -->
<view class="add-cart-section" v-if="item.isSale !== 1">
<view class="add-cart-btn" @click.stop="addToCart(item)">
<u-icon
color="#fff"
size="20"
name="shopping-cart"
></u-icon>
</view>
</view>
<!-- 禁售状态 -->
<view class="sold-out-section" v-if="item.isSale === 1">
<view class="sold-out-btn">暂时缺货</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
<!-- 精品专区的商品容器 -->
<view class="goods-container" v-if="activeTab !== 43">
<scroll-view
class="goodList"
scroll-y="true"
enhanced
:show-scrollbar="false"
>
<view v-for="item in goodList" :key="item.waresCode" class="goodList_i">
<img :src="item.cover1" class="cover" alt="" />
<view class="goodList_ir">
<view class="tit1">
{{ item.waresName }}
</view>
<view class="goodList_ib">
<view class="price-container">
<!-- <text class="currency">¥</text> -->
<text class="price">{{ formatCurrency(item.waresPrice) }}</text>
<text v-if="item.isSale === 1" class="sale-status">已售罄</text>
</view>
</view>
<!-- 加入购物车按钮区域 -->
<view class="add-cart-section" v-if="item.isSale !== 1">
<view class="add-cart-btn" @click.stop="addToCart(item)">
<u-icon color="#fff" size="20" name="shopping-cart"></u-icon>
</view>
</view>
<!-- 禁售状态 -->
<view class="sold-out-section" v-if="item.isSale === 1">
<view class="sold-out-btn">暂时缺货</view>
</view>
</view>
</view>
<view class="list-bottom" v-if="activeTab !== 43">
<text class="bottom-text">— 已显示全部商品 —</text>
</view>
</scroll-view>
</view>
<!-- 底部购物车栏 -->
<view class="cart-bar">
<view class="cart-bar-left" @click="toggleCartDrawer">
<view class="cart-icon-wrapper">
<text class="cart-icon"
><u-icon color="#fff" size="36" name="shopping-cart"> </u-icon
></text>
<view class="cart-badge" v-if="cartTotalCount > 0">
{{ cartTotalCount > 99 ? '99+' : cartTotalCount }}
</view>
</view>
<view class="cart-price" v-if="cartTotalCount > 0">
<text class="cart-price-label">总计:</text>
<text class="cart-price-value">{{
formatCurrency(cartTotalAmount)
}}</text>
</view>
<!-- <view class="cart-empty-tip" v-else>
<text class="cart-empty-text">购物车是空的</text>
</view> -->
</view>
<view
class="cart-bar-btn"
@click="goCheckout"
:class="{ disabled: cartTotalCount === 0 }"
>
去结算
</view>
</view>
<!-- 购物车抽屉 -->
<u-popup
v-if="showCartDrawer"
:show="showCartDrawer"
mode="bottom"
border-radius="30"
:closeable="true"
@close="showCartDrawer = false"
>
<view class="cart-drawer">
<view class="cart-drawer-header">
<text class="cart-drawer-title">购物车</text>
<text class="cart-drawer-count">({{ cartTotalCount }}件商品)</text>
</view>
<scroll-view class="cart-drawer-content" scroll-y="true">
<view
v-for="(item, index) in currentCart"
:key="item.waresCode"
class="cart-item"
>
<view class="cart-item-top">
<image
:src="item.cover1"
class="cart-item-image"
mode="aspectFill"
></image>
<view class="cart-item-info">
<view class="cart-item-name">{{ item.waresName }}</view>
<view class="cart-item-price">{{
formatCurrency(item.waresPrice)
}}</view>
</view>
</view>
<view class="cart-item-actions">
<view class="cart-quantity-control">
<view
class="cart-quantity-btn"
:class="{ disabled: item.quantity <= 1 }"
@click="updateCartQuantity(index, -1)"
>
<text class="cart-quantity-icon"></text>
</view>
<view class="cart-quantity-display">
<text class="cart-quantity-text">{{ item.quantity }}</text>
</view>
<view
class="cart-quantity-btn"
@click="updateCartQuantity(index, 1)"
>
<text class="cart-quantity-icon">+</text>
</view>
</view>
<view class="cart-item-delete" @click="removeFromCart(index)">
<text class="cart-delete-icon">删除</text>
</view>
</view>
</view>
<view v-if="currentCart.length === 0" class="cart-empty">
<text class="cart-empty-text">购物车空空如也~</text>
</view>
</scroll-view>
<view class="cart-drawer-footer" v-if="currentCart.length > 0">
<view class="cart-footer-total">
<text class="cart-footer-label">合计:</text>
<text class="cart-footer-amount">{{
formatCurrency(cartTotalAmount)
}}</text>
</view>
<view class="cart-footer-btn" @click="goCheckout"> 去结算 </view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import * as api from '@/config/login.js'
import * as goodsApi from '@/config/goods.js'
import { getAreaGoods } from '@/config/special-area.js'
import { setToken } from '@/config/auth.js'
import { formatCurrency } from '@/util/index.js'
export default {
data() {
return {
pkParent: '',
goodList: [],
placeParent: '',
activeTab: 43, // 默认选中北大甄选
tabs: [
{
label: '北大甄选',
value: 43,
},
{
label: '精品专区',
value: 41,
},
],
// 分类相关数据
oneList: [], // 一级分类列表
oneId: '', // 当前选中的一级分类ID
twoList: [], // 二级分类列表
twoId: '', // 当前选中的二级分类ID
waresName: '', // 搜索关键词
userInfo: {}, // 用户信息
pkCountry: 1, // 国家ID
categoryLoaded: false, // 分类是否已加载
// 购物车相关数据 - 按tab独立存储
cartData: {
43: [], // 北大甄选的购物车
41: [], // 精品专区的购物车
},
showCartDrawer: false, // 是否显示购物车抽屉
}
},
computed: {
// 当前tab的购物车
currentCart() {
return this.cartData[this.activeTab] || []
},
// 购物车总数量
cartTotalCount() {
return this.currentCart.reduce((total, item) => total + item.quantity, 0)
},
// 购物车总金额
cartTotalAmount() {
return this.currentCart.reduce(
(total, item) => total + item.waresPrice * item.quantity,
0
)
},
},
onLoad(options) {
this.pkParent = options.pkParent
this.userInfo = uni.getStorageSync('User') || {}
this.pkCountry = this.userInfo.pkCountry || 1
this.getToken()
},
methods: {
formatCurrency,
getToken() {
api
.autoLogin({
pkParent: this.pkParent,
})
.then(res => {
setToken(res.data.access_token, res.data.expires_in)
uni.setStorageSync('regiest-login', '1')
// 根据当前tab决定加载方式
if (this.activeTab === 43) {
// 北大甄选 - 需要分类
this.getClassIfy()
} else {
// 精品专区 - 直接获取商品列表
this.getList()
}
this.getCode()
})
},
getCode() {
api.fansConvertCode(this.pkParent).then(res => {
this.placeParent = res.data
uni.setStorageSync('placeParent', this.placeParent)
})
},
getList() {
api
.queryWares({
shareMemberCode: this.pkParent,
specialArea: this.activeTab,
})
.then(res => {
this.goodList = res.data || []
})
},
switchTab(value) {
if (this.activeTab !== value) {
this.activeTab = value
this.goodList = [] // 清空当前列表
// 清空搜索和分类条件
this.clearSearchAndCategory()
// 根据不同tab加载不同数据
if (value === 43) {
// 北大甄选 - 需要分类
this.getClassIfy()
} else {
// 精品专区 - 直接获取商品列表
this.getList()
}
}
},
// 加入购物车
addToCart(item) {
const cart = this.cartData[this.activeTab]
const existingIndex = cart.findIndex(
cartItem => cartItem.waresCode === item.waresCode
)
if (existingIndex > -1) {
// 商品已存在,数量+1
this.$set(
cart[existingIndex],
'quantity',
cart[existingIndex].quantity + 1
)
uni.showToast({
title: '已添加到购物车',
icon: 'success',
duration: 1500,
})
} else {
// 商品不存在,添加新商品
cart.push({
...item,
quantity: 1,
})
uni.showToast({
title: '添加成功',
icon: 'success',
duration: 1500,
})
}
},
// 更新购物车商品数量
updateCartQuantity(index, change) {
const cart = this.cartData[this.activeTab]
const newQuantity = cart[index].quantity + change
if (newQuantity >= 1) {
this.$set(cart[index], 'quantity', newQuantity)
} else if (newQuantity === 0) {
// 数量为0时移除商品
this.removeFromCart(index)
}
},
// 从购物车删除商品
removeFromCart(index) {
uni.showModal({
title: '提示',
content: '确定要删除该商品吗?',
success: res => {
if (res.confirm) {
this.cartData[this.activeTab].splice(index, 1)
uni.showToast({
title: '删除成功',
icon: 'success',
duration: 1500,
})
}
},
zIndex: 10076, // 确保层级高于抽屉
})
},
// 切换购物车抽屉
toggleCartDrawer() {
if (this.cartTotalCount === 0) {
uni.showToast({
title: '购物车是空的',
icon: 'none',
duration: 1500,
})
return
}
this.showCartDrawer = true
},
// 去购买
goCheckout() {
if (this.currentCart.length === 0) {
uni.showToast({
title: '购物车是空的',
icon: 'none',
duration: 1500,
})
return
}
// 关闭抽屉
this.showCartDrawer = false
// 跳转到订单页面,传递购物车数据
const orderData = {
cartList: this.currentCart,
pkParent: this.pkParent,
specialArea: this.activeTab,
}
uni.navigateTo({
url: '/pages/shareArea/hiOrder?allData=' + JSON.stringify(orderData),
})
},
// 获取分类列表(一级)
getClassIfy() {
goodsApi
.classifyList({
pkCountry: this.pkCountry,
specialArea: this.activeTab,
hierarchy: 0,
})
.then(res => {
this.oneList = res.data || []
this.categoryLoaded = true
if (this.oneList.length > 0) {
this.oneId = this.oneList[0].pkId
this.getClassIfyTwo(this.oneList[0].pkId)
this.getAllGoodsWithCategory(this.oneList[0].pkId)
}
})
.catch(err => {
console.error('获取分类失败:', err)
})
},
// 获取分类二级
getClassIfyTwo(pkId) {
goodsApi
.classifyList({
specialArea: this.activeTab,
pkParent: pkId,
hierarchy: 1,
pkCountry: this.pkCountry,
})
.then(res => {
const twoListData = res.data || []
twoListData.unshift({
classifyName: '全部',
pkId: pkId,
})
this.twoList = twoListData
this.twoId = pkId
})
.catch(err => {
console.error('获取二级分类失败:', err)
})
},
// 根据分类获取商品(带搜索功能)
getAllGoodsWithCategory(id) {
const params = {
pkCountry: this.pkCountry,
specialArea: this.activeTab,
pkAreaClassify: id || this.oneId,
shareMemberCode: this.pkParent,
waresName: '',
}
// 如果有搜索关键词,添加到参数中
if (this.waresName.trim()) {
params.waresName = this.waresName.trim()
}
api
.queryWares(params)
.then(res => {
this.goodList = res.data || []
})
.catch(err => {
console.log(err, '...err')
console.error('获取商品列表失败:', err)
this.goodList = []
})
},
// 选择一级分类
selectOneCategory(item) {
this.oneId = item.pkId
this.getAllGoodsWithCategory(item.pkId)
this.getClassIfyTwo(item.pkId)
},
// 选择二级分类
selectTwoCategory(item) {
this.twoId = item.pkId
this.getAllGoodsWithCategory(item.pkId)
},
// 搜索商品
searchGoods() {
this.getAllGoodsWithCategory()
},
// 清空搜索和分类
clearSearchAndCategory() {
this.waresName = ''
this.oneId = ''
this.twoId = ''
this.oneList = []
this.twoList = []
},
},
}
</script>
<style lang="scss" scoped>
.contain {
background: #f8fafc;
min-height: 100vh;
height: 100vh;
display: flex;
flex-direction: column;
}
// 分类和搜索区域样式
.category-container {
background: #ffffff;
border-bottom: 1rpx solid #e2e8f0;
flex: 1;
display: flex;
flex-direction: column;
.category-section {
flex: 1;
display: flex;
height: 0rpx;
.category-left {
width: 200rpx;
background: #f8fafc;
border-right: 1rpx solid #e2e8f0;
overflow-y: auto;
flex-shrink: 0;
.category-item {
padding: 24rpx 20rpx;
font-size: 26rpx;
color: #64748b;
text-align: center;
border-bottom: 1rpx solid #f1f5f9;
transition: all 0.2s ease;
&.category-active {
background: #005bac;
color: #ffffff;
font-weight: 600;
}
&:active {
background: rgba(0, 91, 172, 0.1);
}
}
}
.category-right {
flex: 1;
width: 0;
display: flex;
flex-direction: column;
background: #fff;
.category-scroll {
padding: 20rpx 24rpx;
border-bottom: 1rpx solid #f1f5f9;
.category-tabs {
display: flex;
white-space: nowrap;
.tab-item,
.tab-active {
padding: 12rpx 24rpx;
margin-right: 20rpx;
border-radius: 20rpx;
font-size: 26rpx;
white-space: nowrap;
transition: all 0.2s ease;
}
.tab-item {
background: #f8fafc;
color: #64748b;
border: 1rpx solid #e2e8f0;
}
.tab-active {
background: #005bac;
color: #ffffff;
font-weight: 600;
}
}
}
.search-container {
padding: 20rpx 24rpx;
border-bottom: 1rpx solid #f1f5f9;
.search-input-wrapper {
display: flex;
align-items: center;
background: #f8fafc;
border-radius: 24rpx;
border: 1rpx solid #e2e8f0;
padding: 0 20rpx;
.search-input {
flex: 1;
height: 72rpx;
font-size: 28rpx;
color: #1f2937;
&::placeholder {
color: #9ca3af;
}
}
.search-icon {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
background: #005bac;
border-radius: 50%;
margin-left: 12rpx;
.search-text {
color: #ffffff;
font-size: 24rpx;
}
&:active {
background: #004494;
transform: scale(0.95);
}
}
}
}
// 北大甄选的商品列表容器
.goods-list-container {
flex: 1;
overflow: hidden;
background: #fff;
padding-bottom: 140rpx;
.goodList {
padding: 0;
.goodList_i {
padding: 8rpx;
img {
height: 140rpx;
width: 140rpx;
border-radius: 12rpx;
}
.goodList_ir {
margin-left: 8rpx;
.tit1 {
font-size: 26rpx;
margin-bottom: 8rpx;
}
.goodList_ib {
.price-container {
.price {
font-size: 28rpx;
color: #f82c1a;
}
}
}
.quantity-section {
.quantity-control {
.quantity-btn {
width: 40rpx;
height: 40rpx;
.quantity-icon {
font-size: 24rpx;
}
}
.quantity-display {
height: 40rpx;
}
}
.toBuy {
font-size: 24rpx;
color: #ffffff;
padding: 8rpx 16rpx;
border-radius: 12rpx;
}
.sold-out-btn {
font-size: 24rpx;
color: #ffffff;
padding: 8rpx 16rpx;
border-radius: 12rpx;
}
}
}
}
}
}
}
}
}
// Tab选项卡样式 - 简约大气设计
.tab-container {
// background: #ffffff;
padding: 0;
position: relative;
z-index: 4;
// 顶部装饰线
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3rpx;
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
}
.tab-wrapper {
display: flex;
position: relative;
// background: #ffffff;
// padding: 32rpx 24rpx 24rpx;
.tab-item {
flex: 1;
position: relative;
cursor: pointer;
padding: 24rpx 32rpx;
text-align: center;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
.tab-text {
font-size: 32rpx;
font-weight: 500;
color: #64748b;
transition: all 0.3s ease;
position: relative;
z-index: 2;
}
.tab-line {
display: none;
}
// 悬停效果
&:hover:not(.tab-active) {
.tab-text {
color: #475569;
transform: translateY(-1rpx);
}
}
&.tab-active {
background: rgba(102, 126, 234, 0.08);
.tab-text {
color: #667eea;
font-weight: 600;
}
// 选中指示器 - 底部完整宽度线条
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 3rpx;
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
}
}
&:active {
transform: scale(0.98);
}
}
}
}
// 商品容器区域
.goods-container {
flex: 1;
background: #f8fafc;
padding: 24rpx 24rpx 140rpx;
position: relative;
z-index: 3;
overflow: hidden;
.section-title {
text-align: center;
margin-bottom: 24rpx;
padding: 20rpx 0;
.title-text {
display: block;
color: #1e293b;
font-size: 32rpx;
font-weight: 600;
margin-bottom: 8rpx;
}
.title-desc {
display: block;
color: #64748b;
font-size: 24rpx;
}
}
}
// 商品列表滚动区域
.goodList {
height: 100%;
padding: 0 8rpx;
.goodList_i {
display: flex;
background: #ffffff;
border-radius: 24rpx;
padding: 32rpx;
.cover {
width: 240rpx;
height: 240rpx;
background: #f8fafc;
border: 1rpx solid #e2e8f0;
border-radius: 16rpx;
flex-shrink: 0;
overflow: hidden;
}
.goodList_ir {
margin-left: 24rpx;
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
.tit1 {
color: #1e293b;
font-size: 32rpx;
font-weight: 600;
line-height: 1.4;
margin-bottom: 16rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.sales {
color: #64748b;
font-size: 24rpx;
font-weight: 400;
margin-bottom: 16rpx;
}
.goodList_ib {
margin-bottom: 24rpx;
.price-container {
display: flex;
align-items: baseline;
justify-content: space-between;
.currency {
color: #ff6b35;
font-size: 24rpx;
font-weight: 600;
margin-right: 4rpx;
}
.price {
color: #ff6b35;
font-size: 36rpx;
font-weight: 700;
}
.sale-status {
color: #ef4444;
font-size: 24rpx;
font-weight: 500;
background: rgba(239, 68, 68, 0.1);
padding: 4rpx 12rpx;
border-radius: 12rpx;
border: 1rpx solid rgba(239, 68, 68, 0.2);
}
}
img {
width: 56rpx;
height: 56rpx;
}
}
// 加入购物车按钮区域
.add-cart-section {
display: flex;
justify-content: flex-end;
margin-top: 16rpx;
.add-cart-btn {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #005bac 0%, #003d7a 100%);
color: #ffffff;
border-radius: 50%;
border: none;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 2rpx 8rpx rgba(0, 91, 172, 0.3);
&:active {
transform: scale(0.9);
box-shadow: 0 1rpx 4rpx rgba(0, 91, 172, 0.2);
}
}
}
// 禁售状态区域
.sold-out-section {
display: flex;
justify-content: flex-end;
.sold-out-btn {
background: #f3f4f6;
color: #9ca3af;
padding: 16rpx 32rpx;
text-align: center;
border-radius: 12rpx;
font-size: 24rpx;
font-weight: 500;
border: 1rpx solid #e5e7eb;
cursor: not-allowed;
}
}
.toBuy {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #ffffff;
padding: 16rpx 24rpx;
text-align: center;
border-radius: 12rpx;
font-size: 24rpx;
font-weight: 600;
border: none;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
box-shadow: 0 2rpx 8rpx rgba(102, 126, 234, 0.2);
flex-shrink: 0;
min-width: 120rpx;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.2),
transparent
);
transition: left 0.5s;
}
&:hover {
background: linear-gradient(135deg, #5a67d8 0%, #6b46c1 100%);
transform: translateY(-1rpx);
box-shadow: 0 4rpx 12rpx rgba(102, 126, 234, 0.3);
&::before {
left: 100%;
}
}
&:active {
transform: scale(0.95) translateY(0);
}
}
}
}
.list-bottom {
text-align: center;
padding: 40rpx 0 60rpx;
.bottom-text {
color: #64748b;
font-size: 24rpx;
}
}
}
// 动画定义
@keyframes slideIn {
from {
transform: scaleX(0);
opacity: 0;
}
to {
transform: scaleX(1);
opacity: 1;
}
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-50rpx);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30rpx);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideInUp {
from {
opacity: 0;
transform: translateY(40rpx);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes pulse {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.02);
}
}
@keyframes promoBreathe {
0%,
100% {
transform: scale(1);
box-shadow: 0 8rpx 24rpx rgba(255, 107, 53, 0.4);
}
50% {
transform: scale(1.05);
box-shadow: 0 12rpx 32rpx rgba(255, 107, 53, 0.6);
}
}
@keyframes shimmer {
0% {
left: -100%;
}
50% {
left: -100%;
}
100% {
left: 100%;
}
}
// 商品卡片延迟动画
.goodList_i:nth-child(1) {
animation-delay: 0.1s;
}
.goodList_i:nth-child(2) {
animation-delay: 0.2s;
}
.goodList_i:nth-child(3) {
animation-delay: 0.3s;
}
.goodList_i:nth-child(4) {
animation-delay: 0.4s;
}
.goodList_i:nth-child(5) {
animation-delay: 0.5s;
}
.goodList_i:nth-child(n + 6) {
animation-delay: 0.6s;
}
// 底部购物车栏样式
.cart-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 120rpx;
background: #ffffff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 32rpx;
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.1);
z-index: 1000;
.cart-bar-left {
display: flex;
align-items: center;
gap: 24rpx;
flex: 1;
cursor: pointer;
.cart-icon-wrapper {
position: relative;
width: 80rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #005bac 0%, #003d7a 100%);
border-radius: 50%;
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
}
.cart-icon {
font-size: 40rpx;
}
.cart-badge {
position: absolute;
top: -8rpx;
right: -8rpx;
background: #ff4d4f;
color: #ffffff;
font-size: 20rpx;
font-weight: 600;
padding: 4rpx 8rpx;
border-radius: 20rpx;
min-width: 32rpx;
text-align: center;
border: 2rpx solid #ffffff;
}
}
.cart-price {
display: flex;
align-items: baseline;
.cart-price-label {
font-size: 28rpx;
color: #64748b;
margin-right: 8rpx;
}
.cart-price-value {
font-size: 36rpx;
font-weight: 700;
color: #ff6b35;
}
}
}
.cart-bar-btn {
background: linear-gradient(135deg, #005bac 0%, #003d7a 100%);
color: #ffffff;
padding: 20rpx 48rpx;
border-radius: 60rpx;
font-size: 28rpx;
font-weight: 600;
box-shadow: 0 4rpx 12rpx rgba(0, 91, 172, 0.4);
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
box-shadow: 0 2rpx 8rpx rgba(0, 91, 172, 0.3);
}
&.disabled {
background: #cbd5e1;
color: #94a3b8;
box-shadow: none;
cursor: not-allowed;
&:active {
transform: none;
}
}
}
.cart-empty-tip {
.cart-empty-text {
font-size: 26rpx;
color: #94a3b8;
}
}
}
// 购物车抽屉样式
.cart-drawer {
background: #ffffff;
max-height: 80vh;
display: flex;
flex-direction: column;
.cart-drawer-header {
padding: 32rpx;
border-bottom: 1rpx solid #f1f5f9;
display: flex;
align-items: center;
justify-content: center;
gap: 16rpx;
.cart-drawer-title {
font-size: 32rpx;
font-weight: 600;
color: #1e293b;
}
.cart-drawer-count {
font-size: 28rpx;
color: #64748b;
}
}
.cart-drawer-content {
flex: 1;
max-height: 60vh;
overflow-y: auto;
.cart-item {
display: flex;
flex-direction: column;
padding: 24rpx 32rpx;
border-bottom: 1rpx solid #f1f5f9;
gap: 20rpx;
.cart-item-top {
display: flex;
align-items: center;
gap: 24rpx;
.cart-item-image {
width: 120rpx;
height: 120rpx;
border-radius: 12rpx;
background: #f8fafc;
border: 1rpx solid #e2e8f0;
flex-shrink: 0;
}
.cart-item-info {
flex: 1;
min-width: 0;
.cart-item-name {
font-size: 28rpx;
color: #1e293b;
font-weight: 500;
margin-bottom: 12rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.cart-item-price {
font-size: 32rpx;
color: #ff6b35;
font-weight: 700;
}
}
}
.cart-item-actions {
display: flex;
align-items: center;
justify-content: space-between;
.cart-quantity-control {
display: flex;
align-items: center;
background: #f8fafc;
border-radius: 12rpx;
border: 1rpx solid #e2e8f0;
overflow: hidden;
.cart-quantity-btn {
width: 48rpx;
height: 48rpx;
display: flex;
align-items: center;
justify-content: center;
background: #ffffff;
transition: all 0.2s ease;
.cart-quantity-icon {
font-size: 28rpx;
font-weight: 600;
color: #005bac;
}
&.disabled {
opacity: 0.3;
.cart-quantity-icon {
color: #9ca3af;
}
}
&:not(.disabled):active {
background: #f1f5f9;
transform: scale(0.9);
}
}
.cart-quantity-display {
min-width: 60rpx;
height: 48rpx;
display: flex;
align-items: center;
justify-content: center;
background: #ffffff;
border-left: 1rpx solid #e2e8f0;
border-right: 1rpx solid #e2e8f0;
.cart-quantity-text {
font-size: 26rpx;
font-weight: 600;
color: #1f2937;
}
}
}
.cart-item-delete {
padding: 12rpx 24rpx;
background: rgba(239, 68, 68, 0.1);
border-radius: 8rpx;
transition: all 0.2s ease;
.cart-delete-icon {
font-size: 26rpx;
color: #ef4444;
font-weight: 500;
}
&:active {
background: rgba(239, 68, 68, 0.2);
transform: scale(0.95);
}
}
}
}
.cart-empty {
padding: 120rpx 0;
text-align: center;
.cart-empty-text {
font-size: 28rpx;
color: #9ca3af;
}
}
}
.cart-drawer-footer {
padding: 24rpx 32rpx;
border-top: 1rpx solid #f1f5f9;
display: flex;
align-items: center;
justify-content: space-between;
background: #ffffff;
.cart-footer-total {
display: flex;
align-items: baseline;
.cart-footer-label {
font-size: 28rpx;
color: #64748b;
margin-right: 8rpx;
}
.cart-footer-amount {
font-size: 40rpx;
font-weight: 700;
color: #ff6b35;
}
}
.cart-footer-btn {
background: linear-gradient(135deg, #005bac 0%, #003d7a 100%);
color: #ffffff;
padding: 20rpx 48rpx;
border-radius: 60rpx;
font-size: 28rpx;
font-weight: 600;
box-shadow: 0 4rpx 12rpx rgba(0, 91, 172, 0.4);
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
box-shadow: 0 2rpx 8rpx rgba(0, 91, 172, 0.3);
}
}
}
}
</style>