feat(uniapp): 美化购物车页并展示所属门店
重构购物车页样式,展示门店与取餐方式;门店信息本地持久化,结算逻辑保持原行为。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
2c3618f74d
commit
9384c68662
3 files changed
+445
-163
No files matched your search
@@ -41,6 +41,8 @@
|
|||||||
"style" :
|
"style" :
|
||||||
{
|
{
|
||||||
"navigationBarTitleText": "购物车",
|
"navigationBarTitleText": "购物车",
|
||||||
|
"navigationBarBackgroundColor": "#fff3e6",
|
||||||
|
"backgroundColor": "#fff3e6",
|
||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,260 +1,539 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<view class="cart-page">
|
||||||
<uv-navbar
|
<uv-navbar
|
||||||
:fixed="false"
|
:fixed="false"
|
||||||
:title="title"
|
title="购物车"
|
||||||
left-arrow
|
bgColor="transparent"
|
||||||
@leftClick="$onClickLeft"
|
leftIcon=""
|
||||||
/>
|
/>
|
||||||
<view class="cart-page">
|
|
||||||
<view class="cart-page__header flex justify-between">
|
<!-- 门店信息 -->
|
||||||
<text>已点{{ getCartGoodsNumber }}份</text>
|
<view class="cart-store" @tap="selectShop" v-if="store && store.id">
|
||||||
<text @tap="handleCartClear">清空</text>
|
<image
|
||||||
|
v-if="store.image"
|
||||||
|
class="cart-store__img"
|
||||||
|
:src="store.image"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
|
<view v-else class="cart-store__img cart-store__img--placeholder">
|
||||||
|
<uv-icon name="home-fill" size="22" color="#F28C38" />
|
||||||
</view>
|
</view>
|
||||||
<scroll-view class="cart-page__list" scroll-y>
|
<view class="cart-store__main">
|
||||||
<view class="cart-page__list-inner">
|
<view class="cart-store__name-row">
|
||||||
<uv-empty mode="car" v-if="cart.length == 0"></uv-empty>
|
<text class="cart-store__name">{{ store.name || '未选择门店' }}</text>
|
||||||
<view class="cart-item" v-for="(item, index) in cart" :key="index">
|
<view class="cart-store__tag">{{ orderTypeLabel }}</view>
|
||||||
<view class="cart-item__info">
|
|
||||||
<view class="cart-item__name">{{ item.name }}</view>
|
|
||||||
<view class="cart-item__props">{{ item.valueStr }}</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="cart-item__price">
|
<view class="cart-store__sub">
|
||||||
<text>¥{{ item.price }}</text>
|
{{ storeHint }}
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="cart-store__switch">
|
||||||
|
<text>切换</text>
|
||||||
|
<uv-icon name="arrow-right" size="12" color="#F28C38" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="cart-store cart-store--empty" @tap="selectShop" v-else>
|
||||||
|
<view class="cart-store__img cart-store__img--placeholder">
|
||||||
|
<uv-icon name="map-fill" size="22" color="#F28C38" />
|
||||||
|
</view>
|
||||||
|
<view class="cart-store__main">
|
||||||
|
<view class="cart-store__name">请先选择门店</view>
|
||||||
|
<view class="cart-store__sub">选择门店后即可点餐结算</view>
|
||||||
|
</view>
|
||||||
|
<view class="cart-store__switch">
|
||||||
|
<text>去选择</text>
|
||||||
|
<uv-icon name="arrow-right" size="12" color="#F28C38" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 商品列表 -->
|
||||||
|
<view class="cart-panel">
|
||||||
|
<view class="cart-panel__header">
|
||||||
|
<text class="cart-panel__title">已点 {{ getCartGoodsNumber }} 件</text>
|
||||||
|
<text
|
||||||
|
v-if="cart.length"
|
||||||
|
class="cart-panel__clear"
|
||||||
|
@tap="handleCartClear"
|
||||||
|
>清空</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<scroll-view class="cart-panel__list" scroll-y>
|
||||||
|
<uv-empty v-if="!cart.length" mode="car" text="购物车还是空的" />
|
||||||
|
<view
|
||||||
|
v-for="(item, index) in cart"
|
||||||
|
:key="index"
|
||||||
|
class="cart-item"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
v-if="item.image"
|
||||||
|
class="cart-item__img"
|
||||||
|
:src="item.image"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
|
<view v-else class="cart-item__img cart-item__img--placeholder" />
|
||||||
|
<view class="cart-item__body">
|
||||||
|
<view class="cart-item__top">
|
||||||
|
<text class="cart-item__name">{{ item.name }}</text>
|
||||||
|
<text class="cart-item__price">¥{{ item.price }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="cart-item__props" v-if="item.valueStr">{{ item.valueStr }}</view>
|
||||||
<view class="cart-item__controls">
|
<view class="cart-item__controls">
|
||||||
<button type="default" plain size="mini" class="cart-item__btn" hover-class="none"
|
<button
|
||||||
@tap="handleCartItemReduce(index)">
|
type="default"
|
||||||
<view class="iconfont iconsami-select"></view>
|
plain
|
||||||
|
class="cart-item__btn"
|
||||||
|
hover-class="none"
|
||||||
|
@tap="handleCartItemReduce(index)"
|
||||||
|
>
|
||||||
|
<text class="iconfont iconsami-select"></text>
|
||||||
</button>
|
</button>
|
||||||
<view class="cart-item__qty">{{ item.number }}</view>
|
<text class="cart-item__qty">{{ item.number }}</text>
|
||||||
<button type="primary" class="cart-item__btn" size="min" hover-class="none"
|
<button
|
||||||
@tap="handleCartItemAdd(index)">
|
type="primary"
|
||||||
<view class="iconfont iconadd-select"></view>
|
class="cart-item__btn cart-item__btn--add"
|
||||||
|
hover-class="none"
|
||||||
|
@tap="handleCartItemAdd(index)"
|
||||||
|
>
|
||||||
|
<text class="iconfont iconadd-select"></text>
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="cart-panel__spacer" />
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
<view class="fixed-bottom flex justify-between align-center bg-white">
|
|
||||||
<view class="mx-2 font-weight-light">应付:<text class="text-danger">¥{{ getCartGoodsPrice }}</text></view>
|
<!-- 底部结算栏 -->
|
||||||
<view><uv-button type="primary" :customStyle="customStyle" size="large" text="去结算" @click="toPay"></uv-button></view>
|
<view class="cart-bar" v-if="cart.length">
|
||||||
|
<view class="cart-bar__info">
|
||||||
|
<view class="cart-bar__store" v-if="store && store.name">
|
||||||
|
{{ store.name }} · {{ orderTypeLabel }}
|
||||||
|
</view>
|
||||||
|
<view class="cart-bar__price-row">
|
||||||
|
<text class="cart-bar__label">合计</text>
|
||||||
|
<text class="cart-bar__yen">¥</text>
|
||||||
|
<text class="cart-bar__price">{{ getCartGoodsPrice }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<button class="cart-bar__btn" @tap="toPay">去结算</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<uv-toast ref="uToast" />
|
||||||
</view>
|
</view>
|
||||||
<uv-toast ref="uToast"></uv-toast>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import { ref, computed } from 'vue'
|
||||||
ref,
|
|
||||||
computed
|
|
||||||
} from 'vue'
|
|
||||||
import { useMainStore } from '@/store/store'
|
import { useMainStore } from '@/store/store'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { onLoad,onShow} from '@dcloudio/uni-app'
|
import { onShow } from '@dcloudio/uni-app'
|
||||||
|
import { kmUnit } from '@/utils/util'
|
||||||
|
|
||||||
const main = useMainStore()
|
const main = useMainStore()
|
||||||
const { orderType,address, store,location,isLogin } = storeToRefs(main)
|
const { orderType, store, isLogin } = storeToRefs(main)
|
||||||
const title = ref('购物车')
|
|
||||||
const cart = ref([])
|
const cart = ref([])
|
||||||
const uToast = ref()
|
const uToast = ref()
|
||||||
|
|
||||||
// onLoad(() => {
|
const orderTypeLabel = computed(() =>
|
||||||
// cart.value = uni.getStorageSync('cart')
|
orderType.value === 'takeout' ? '外卖' : '自取'
|
||||||
// })
|
)
|
||||||
onShow(() => {
|
|
||||||
//cart.value = []
|
const storeHint = computed(() => {
|
||||||
cart.value = uni.getStorageSync('cart')
|
if (!store.value || !store.value.id) return '点击选择门店'
|
||||||
})
|
if (orderType.value === 'takeout') {
|
||||||
const getCartGoodsNumber = computed(() => { //计算购物车总数
|
if (store.value.distance > 0) {
|
||||||
if(cart.value.length == 0) {
|
return `配送距离约 ${store.value.distance}km`
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
return '本店外卖配送'
|
||||||
|
}
|
||||||
|
if (store.value.dis) {
|
||||||
|
return `距离您 ${kmUnit(store.value.dis)}`
|
||||||
|
}
|
||||||
|
return '到店自取,下单免排队'
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
cart.value = uni.getStorageSync('cart') || []
|
||||||
|
// 从点餐页切过来时 pinia 里通常有门店;冷启动进购物车则从本地恢复
|
||||||
|
if (!store.value?.id) {
|
||||||
|
const cachedStore = uni.getStorageSync('store')
|
||||||
|
if (cachedStore && cachedStore.id) {
|
||||||
|
main.SET_STORE(cachedStore)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const getCartGoodsNumber = computed(() => {
|
||||||
|
if (!cart.value.length) return 0
|
||||||
return cart.value.reduce((acc, cur) => acc + cur.number, 0)
|
return cart.value.reduce((acc, cur) => acc + cur.number, 0)
|
||||||
})
|
})
|
||||||
const getCartGoodsPrice = computed(() =>{ //计算购物车总价
|
|
||||||
if(cart.value.length == 0) {
|
const getCartGoodsPrice = computed(() => {
|
||||||
return 0
|
if (!cart.value.length) return '0.00'
|
||||||
}
|
const price = cart.value.reduce((acc, cur) => acc + cur.number * cur.price, 0)
|
||||||
let price = cart.value.reduce((acc, cur) => acc + cur.number * cur.price, 0);
|
return parseFloat(price).toFixed(2)
|
||||||
return parseFloat(price).toFixed(2);
|
|
||||||
})
|
|
||||||
const customStyle = computed(() =>{
|
|
||||||
return {
|
|
||||||
paddingLeft:'60rpx',
|
|
||||||
paddingRight:'60rpx'
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const selectShop = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/components/pages/shop/shop'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const handleCartItemAdd = (index) => {
|
const handleCartItemAdd = (index) => {
|
||||||
cart.value[index].number += 1
|
cart.value[index].number += 1
|
||||||
uni.setStorageSync('cart', JSON.parse(JSON.stringify(cart.value)))
|
uni.setStorageSync('cart', JSON.parse(JSON.stringify(cart.value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCartItemReduce = (index) => {
|
const handleCartItemReduce = (index) => {
|
||||||
if (cart.value[index].number === 1) {
|
if (cart.value[index].number === 1) {
|
||||||
cart.value.splice(index, 1)
|
cart.value.splice(index, 1)
|
||||||
} else {
|
} else {
|
||||||
cart.value[index].number -= 1
|
cart.value[index].number -= 1
|
||||||
}
|
}
|
||||||
if (!cart.value.length) {
|
|
||||||
cartPopupVisible.value = false
|
|
||||||
}
|
|
||||||
uni.setStorageSync('cart', JSON.parse(JSON.stringify(cart.value)))
|
uni.setStorageSync('cart', JSON.parse(JSON.stringify(cart.value)))
|
||||||
}
|
}
|
||||||
const handleCartClear = () => { //清空购物车
|
|
||||||
|
const handleCartClear = () => {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
content: '确定清空购物车么',
|
content: '确定清空购物车么',
|
||||||
success: ({
|
success: ({ confirm }) => {
|
||||||
confirm
|
|
||||||
}) => {
|
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
cart.value = []
|
cart.value = []
|
||||||
uni.setStorageSync('cart', JSON.parse(JSON.stringify(cart.value)))
|
uni.setStorageSync('cart', [])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const toPay = () => {
|
const toPay = () => {
|
||||||
|
if (!cart.value.length) {
|
||||||
if(cart.value.length == 0){
|
uToast.value.show({ message: '请先去点餐哦', type: 'error' })
|
||||||
uToast.value.show({message:'请先去点餐哦',type: 'error'});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isLogin.value) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/components/pages/login/login'
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
} else {
|
|
||||||
if (store.value.status == 0) {
|
|
||||||
uToast.value.show({message:'不在店铺营业时间内',type: 'error'});
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// 判断当前是否在配送范围内
|
if (!isLogin.value) {
|
||||||
if (orderType.value == 'takeout' && store.value.distance < store.value.far) {
|
uni.navigateTo({ url: '/pages/components/pages/login/login' })
|
||||||
uToast.value.show({message:'选中的地址不在配送范围',type: 'error'});
|
return
|
||||||
return;
|
}
|
||||||
|
if (store.value?.status == 0) {
|
||||||
|
uToast.value.show({ message: '不在店铺营业时间内', type: 'error' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (orderType.value == 'takeout' && store.value?.distance < store.value?.far) {
|
||||||
|
uToast.value.show({ message: '选中的地址不在配送范围', type: 'error' })
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uni.showLoading({
|
uni.showLoading({ title: '加载中' })
|
||||||
title: '加载中'
|
|
||||||
})
|
|
||||||
uni.setStorageSync('cart', JSON.parse(JSON.stringify(cart.value)))
|
uni.setStorageSync('cart', JSON.parse(JSON.stringify(cart.value)))
|
||||||
|
uni.navigateTo({ url: '/pages/components/pages/pay/pay' })
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/components/pages/pay/pay'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
uni.hideLoading()
|
uni.hideLoading()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
// 购物车页局部 token(与 uni.scss 全局变量配合)
|
$bg-top: #fff3e6;
|
||||||
$cart-list-max-height: 60vh;
|
$bg-bottom: #ffffff;
|
||||||
$cart-list-min-height: 1vh;
|
$accent: #f28c38;
|
||||||
$cart-list-bottom-space: 156rpx;
|
$accent-deep: #ff6817;
|
||||||
$cart-price-offset: 120rpx;
|
$text-main: #2b2b2b;
|
||||||
$cart-control-size: 46rpx;
|
$text-sub: #9a9590;
|
||||||
$cart-divider-height: 2rpx;
|
$card-radius: 24rpx;
|
||||||
$cart-header-color: #5a5b5c;
|
|
||||||
$cart-gap-sm: 10rpx;
|
|
||||||
|
|
||||||
.cart-page {
|
.cart-page {
|
||||||
--cart-control-size: #{$cart-control-size};
|
min-height: 100vh;
|
||||||
--cart-list-max-height: #{$cart-list-max-height};
|
padding: 0 24rpx 200rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
&__header {
|
background: linear-gradient(180deg, $bg-top 0%, #fff8f0 40%, $bg-bottom 100%);
|
||||||
padding: $cart-gap-sm $spacing-row-lg;
|
|
||||||
font-size: $font-size-sm;
|
|
||||||
text-align: right;
|
|
||||||
color: $cart-header-color;
|
|
||||||
background-color: $bg-color-primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__list {
|
|
||||||
width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
min-height: $cart-list-min-height;
|
|
||||||
max-height: var(--cart-list-max-height);
|
|
||||||
background-color: $text-color-white;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__list-inner {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0 $spacing-row-lg;
|
|
||||||
margin-bottom: $cart-list-bottom-space;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cart-item {
|
.cart-store {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
padding: 24rpx;
|
||||||
padding: $spacing-row-lg 0;
|
margin-bottom: 20rpx;
|
||||||
position: relative;
|
border-radius: $card-radius;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 8rpx 24rpx rgba(180, 120, 60, 0.08);
|
||||||
|
|
||||||
&::after {
|
&--empty {
|
||||||
content: '';
|
border: 2rpx dashed #f0d9bd;
|
||||||
position: absolute;
|
background: #fffaf4;
|
||||||
bottom: 0;
|
box-shadow: none;
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: $cart-divider-height;
|
|
||||||
background-color: $border-color;
|
|
||||||
transform: scaleY(0.6);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__info {
|
&__img {
|
||||||
flex: 1;
|
width: 88rpx;
|
||||||
|
height: 88rpx;
|
||||||
|
border-radius: 18rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
background: #fff3e6;
|
||||||
|
|
||||||
|
&--placeholder {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
align-items: center;
|
||||||
overflow: hidden;
|
justify-content: center;
|
||||||
margin-right: $spacing-row-lg;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__main {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__name-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__name {
|
&__name {
|
||||||
font-size: $font-size-sm;
|
font-size: 30rpx;
|
||||||
color: $text-color-base;
|
font-weight: 700;
|
||||||
|
color: $text-main;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
max-width: 360rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__props {
|
&__tag {
|
||||||
font-size: $font-size-sm;
|
flex-shrink: 0;
|
||||||
color: $text-color-assist;
|
padding: 4rpx 14rpx;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
font-size: 20rpx;
|
||||||
|
color: #fff;
|
||||||
|
background: linear-gradient(90deg, #ff9b20, #ff6817);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__sub {
|
||||||
|
margin-top: 8rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: $text-sub;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__switch {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-left: 12rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: $accent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cart-panel {
|
||||||
|
border-radius: $card-radius;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 8rpx 24rpx rgba(180, 120, 60, 0.08);
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 28rpx 28rpx 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: $text-main;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__clear {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: $text-sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__list {
|
||||||
|
max-height: calc(100vh - 480rpx);
|
||||||
|
min-height: 320rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__spacer {
|
||||||
|
height: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cart-item {
|
||||||
|
display: flex;
|
||||||
|
padding: 24rpx 28rpx;
|
||||||
|
border-bottom: 1rpx solid #f3ebe3;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__img {
|
||||||
|
width: 128rpx;
|
||||||
|
height: 128rpx;
|
||||||
|
border-radius: 18rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
background: #fff3e6;
|
||||||
|
|
||||||
|
&--placeholder {
|
||||||
|
background: linear-gradient(135deg, #fff3e6, #f5e6d4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__body {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__top {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: $text-main;
|
||||||
|
line-height: 1.35;
|
||||||
|
}
|
||||||
|
|
||||||
&__price {
|
&__price {
|
||||||
margin-right: $cart-price-offset;
|
flex-shrink: 0;
|
||||||
font-size: $font-size-base;
|
font-size: 30rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: $accent-deep;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__props {
|
||||||
|
margin-top: 8rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: $text-sub;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__controls {
|
&__controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: flex-end;
|
||||||
}
|
margin-top: auto;
|
||||||
|
padding-top: 12rpx;
|
||||||
&__btn,
|
|
||||||
&__qty {
|
|
||||||
width: var(--cart-control-size);
|
|
||||||
height: var(--cart-control-size);
|
|
||||||
line-height: var(--cart-control-size);
|
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__btn {
|
&__btn {
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border-radius: $border-radius-circle;
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: $accent;
|
||||||
|
border: 2rpx solid $accent !important;
|
||||||
|
background: #fff;
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--add {
|
||||||
|
color: #fff;
|
||||||
|
background: $accent;
|
||||||
|
border-color: $accent !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__qty {
|
&__qty {
|
||||||
font-size: $font-size-base;
|
min-width: 52rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: $text-main;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cart-bar {
|
||||||
|
position: fixed;
|
||||||
|
left: 24rpx;
|
||||||
|
right: 24rpx;
|
||||||
|
bottom: calc(24rpx + env(safe-area-inset-bottom));
|
||||||
|
/* #ifdef H5 */
|
||||||
|
bottom: calc(24rpx + var(--window-bottom, 0px));
|
||||||
|
/* #endif */
|
||||||
|
z-index: 100;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 112rpx;
|
||||||
|
padding: 0 10rpx 0 32rpx;
|
||||||
|
border-radius: 56rpx;
|
||||||
|
background: #2f241c;
|
||||||
|
box-shadow: 0 12rpx 32rpx rgba(47, 36, 28, 0.28);
|
||||||
|
|
||||||
|
&__info {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
padding-right: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__store {
|
||||||
|
font-size: 20rpx;
|
||||||
|
color: rgba(255, 255, 255, 0.62);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__price-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-top: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__label {
|
||||||
|
margin-right: 10rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: rgba(255, 255, 255, 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__yen {
|
||||||
|
font-size: 24rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__price {
|
||||||
|
font-size: 40rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__btn {
|
||||||
|
height: 88rpx;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 48rpx;
|
||||||
|
border-radius: 44rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #fff;
|
||||||
|
background: linear-gradient(90deg, #ff9b20, #ff6817);
|
||||||
|
line-height: 88rpx;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -51,6 +51,7 @@ export const useMainStore = defineStore('main', {
|
|||||||
},
|
},
|
||||||
SET_STORE(store) {
|
SET_STORE(store) {
|
||||||
this.store = store
|
this.store = store
|
||||||
|
uni.setStorageSync('store', store || {})
|
||||||
},
|
},
|
||||||
SET_CART(cart) {
|
SET_CART(cart) {
|
||||||
this.cart = cart
|
this.cart = cart
|
||||||
|
|||||||
Reference in new issue
Block a user