3834 lines
101 KiB
Vue
3834 lines
101 KiB
Vue
<template>
|
||
<view>
|
||
<Nav />
|
||
<!-- 顶部面板 -->
|
||
<view class="top--panel" :class="{ grayscale: !isBusinessTime }">
|
||
<template v-if="shopExtend">
|
||
<image class="panelimgbackground"
|
||
:src="shopExtend ? shopExtend.value : 'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/shopDetails/topBanner.png'"
|
||
mode="aspectFill" v-if="!isJsonArrayString(shopExtend.value)"></image>
|
||
<swiper class="panelimgbackground" autoplay indicator-dots circular v-else>
|
||
<swiper-item class="panelimgbackground" v-for="(item, index) in JSON.parse(shopExtend.value)"
|
||
:key="index">
|
||
<image class="panelimgbackground" :src="item" mode="aspectFill"></image>
|
||
</swiper-item>
|
||
</swiper>
|
||
</template>
|
||
<template v-else>
|
||
<image class="panelimgbackground"
|
||
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/shopDetails/topBanner.png" mode="aspectFill">
|
||
</image>
|
||
</template>
|
||
<view class="panelone">
|
||
<text>
|
||
{{ shopInfo.shopName }}
|
||
</text>
|
||
<view class="paneltow">距离您{{ juli }}km</view>
|
||
<!-- <up-icon name="arrow-right" color="#999999" size="14"></up-icon> -->
|
||
</view>
|
||
<view class="new-user-discount u-font-28" v-if="newUserDiscount&&newUserDiscount.amount">
|
||
<text class="">新客立减¥</text>
|
||
<text class="u-font-32">{{ newUserDiscount.amount }}</text>
|
||
<!-- <text class="u-m-l-60">新客可随机减免金额</text> -->
|
||
</view>
|
||
<view class="panelthere flex-between">
|
||
<view class="paneltheretext">
|
||
营业时间:{{ (shopInfo.businessStartDay || '--') + ' 至 ' + (shopInfo.businessEndDay || '--') }}
|
||
{{ endTimeref.startTime }} -
|
||
{{ endTimeref.endTime < '05' ? ` 凌晨${endTimeref.endTime}` : endTimeref.endTime }}
|
||
</view>
|
||
<view class="flex-start" @click="callChildMethod">
|
||
<view style="margin-right: 14rpx">查看</view>
|
||
<up-icon name="arrow-down" color="#999999" size="14"></up-icon>
|
||
</view>
|
||
</view>
|
||
<!-- 本店招牌菜 -->
|
||
<view class="panelfour" v-if="shopProductList.hots && shopProductList.hots.length > 0">本店招牌菜</view>
|
||
<view class="panelfive">
|
||
<scroll-view :scroll-x="true" :scroll-with-animation="false">
|
||
<view class="panelfive_list">
|
||
<view class="panelfiveitem" @click="clickspecifications(item, index, index, '热销')"
|
||
v-for="(item, index) in shopProductList.hots" :key="index">
|
||
|
||
|
||
<view class="relative">
|
||
<image @click.stop="getProductImgs(item)" class="panelfiveitemimage"
|
||
:src="item.coverImg" mode="aspectFill"></image>
|
||
<view class="limitDiscount" v-if="showLimitDiscount(item)">
|
||
限时折扣{{ limitDiscountCountdown }}</view>
|
||
<!-- <view class="limitDiscount" v-if="item.is_time_discount">
|
||
限时折扣{{ limitDiscountCountdown }}</view> -->
|
||
<view class="stock_warning"
|
||
v-if="item.isStock&&item.stockNumber<=10&&item.stockNumber>0">
|
||
仅剩{{item.stockNumber}}份</view>
|
||
</view>
|
||
|
||
<view class="vifgoodsImg flex-center"
|
||
v-if="item.isSale == 0 || (item.isSaleTime == 0 && !item.isSaleTimeshow) || item.isSoldStock == 1 || (item.isStock == 1 && item.stockNumber <= 0)">
|
||
<image v-if="item.isSale == 0" src="@/static/ztt/icon_goods_yxj.svg"
|
||
style="width: 200rpx; height: 100%" mode=""></image>
|
||
<image v-else-if="item.isSaleTime == 0 && !item.isSaleTimeshow"
|
||
src="@/static/ztt/icon_goods_wks.svg" style="width: 200rpx; height: 100%" mode="">
|
||
</image>
|
||
<image v-else-if="item.isSoldStock == 1" src="@/static/ztt/icon_goods_sq.svg"
|
||
style="width: 200rpx; height: 100%" mode=""></image>
|
||
<image v-else-if="item.isStock == 1 && item.stockNumber <= 0"
|
||
src="@/static/ztt/icon_goods_kcbz.svg" style="width: 200rpx; height: 100%" mode="">
|
||
</image>
|
||
</view>
|
||
<view class="u-flex u-m-t-32 u-row-between">
|
||
<view class="panelfiveitemone">
|
||
{{ item.name }}
|
||
</view>
|
||
<text class="top-tag">招牌</text>
|
||
</view>
|
||
|
||
<view class="panelfiveitemtow">本店回头客第{{ index + 1 }}名</view>
|
||
<view class="panelfiveitemthere flex-between">
|
||
<view class="describe" v-if="item.suitNum > 1 && item.type != 'sku'"
|
||
style="font-size: 20rpx; margin-top: 10rpx">
|
||
「{{ item.suitNum }}{{ item.unitName }}起点」
|
||
</view>
|
||
</view>
|
||
|
||
<!-- <view class="panelfiveitemfour">
|
||
{{item.shortTitle?item.shortTitle:''}}
|
||
</view>
|
||
<view class="panelfiveitemfive">
|
||
月售{{item.stockNumber}}
|
||
</view> -->
|
||
<view v-if="item.isSoldStock == 1 || (item.isSaleTime == 0 && !item.isSaleTimeshow)"
|
||
class="flex-between" style="margin-top: 32rpx; margin-bottom: 48rpx">
|
||
<view class="panelfiveitemsex flex-between">
|
||
<view class="panelfiveitemsex_oen">
|
||
<text class="tips"
|
||
:class="shopInfo.isVip == 0 || shopInfo.isMemberPrice == 0 ? 'lineThrough' : ''">¥</text>
|
||
<!-- 会员价与价格 -->
|
||
<text class="price">
|
||
{{ shopUserInfo.isVip == 1 && shopUserInfo.isMemberPrice == 1 ? item.memberPrice || item.salePrice : item.salePrice }}
|
||
</text>
|
||
<!-- 单位 -->
|
||
<text class="unit" v-if="item.unitName">/{{ item.unitName }}</text>
|
||
|
||
<text class="old-price">¥{{ item.salePrice }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="panelfiveitemNum">
|
||
<view class="sku-wrap flex-center" style="background-color: #cecece">
|
||
<text class="t" v-if="item.isSaleTime == 0 && !item.isSaleTimeshow">未开售</text>
|
||
<text class="t" v-if="item.isSoldStock == 1">已售罄</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view v-else class="flex-between"
|
||
style="margin-top: 32rpx; margin-bottom: 48rpx; flex-wrap: inherit">
|
||
<view class="panelfiveitemsex flex-between">
|
||
<view class="panelfiveitemsex_oen">
|
||
<text class="tips"
|
||
:class="shopInfo.isVip == 0 || shopInfo.isMemberPrice == 0 ? 'lineThrough' : ''">¥</text>
|
||
<!-- 会员价与价格 -->
|
||
<view class="price">
|
||
<GoodsPrice :limitDiscount="cartStore.limitTimeDiscount" :cart="item"
|
||
:shopUserInfo="shopUserInfo" :key="item.id" :shopInfo="shopInfo">
|
||
</GoodsPrice>
|
||
</view>
|
||
|
||
<text class="unit" v-if="item.unitName">/{{ item.unitName }}</text>
|
||
<text class="old-price">¥{{ item.salePrice }}</text>
|
||
<!-- <text v-if="item.suitNum>1 && item.type!= 'sku'"
|
||
style="font-size: 16rpx;">「{{item.suitNum}}{{item.unitName}}起点」</text> -->
|
||
</view>
|
||
</view>
|
||
<!-- single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券 -->
|
||
<view class="panelfiveitemNum">
|
||
<!-- v-if="item.type == 'single'|| item.type == 'weight' || item.type == 'coupon' || (item.type == 'package' && item.groupType=='0')" -->
|
||
<view class="sku-wrap flex-center"
|
||
v-if="item.type == 'sku' || (item.type == 'package' && item.groupType == '1')"
|
||
@click.stop="clickspecifications(item, index, index1)">
|
||
<text class="t no-wrap" v-if="item.groupType == '1'">选择套餐</text>
|
||
<text class="t" v-else>选规格</text>
|
||
<!-- <text class="dot num"
|
||
v-if="item.cartNumber > 0">{{ ifcartNumber(item) < 99 ? ifcartNumber(item) : '99+' }}</text> -->
|
||
<text class="dot num"
|
||
v-if="returnGoodsImCartNum(item)">{{ returnGoodsImCartNum(item) < 99 ? returnGoodsImCartNum(item) : '99+' }}</text>
|
||
</view>
|
||
<view class="Controls" v-else>
|
||
<view class="btn" v-if="item.cartNumber != '0'">
|
||
<up-icon name="minus-circle-fill" color="#E9AB7A" size="25"></up-icon>
|
||
<view class="btnClick" @tap.stop="singleclick(item, '-')"></view>
|
||
<!-- <view class="btnClick"
|
||
@tap.stop="$u.throttle(() => singleclick(item, '-'), 500)"></view> -->
|
||
</view>
|
||
<!-- <text class="num">{{ ifcartNumber(item) }}</text> -->
|
||
|
||
<text class="dot num"
|
||
v-if="returnGoodsImCartNum(item1)">{{ returnGoodsImCartNum(item1) < 99 ? returnGoodsImCartNum(item1) : '99+' }}</text>
|
||
<view class="btn">
|
||
<up-icon name="plus-circle-fill" color="#E9AB7A" size="25"></up-icon>
|
||
<!-- <view class="btnClick"
|
||
@tap.stop="$u.throttle(() => singleclick(item, '+'), 500)"></view> -->
|
||
<view class="btnClick" @tap.stop="singleclick(item, '+')"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 滚动区域 -->
|
||
<view class="scroll-panel" id="scroll-panel" :class="{ grayscale: !isBusinessTime }">
|
||
<view class="list-box">
|
||
<view class="left" :style="{ top: `${store.height}px` }">
|
||
<scroll-view :scroll-into-view="leftIntoView" :scroll-with-animation="false" :scroll-y="true"
|
||
:style="{ height: `${store.screenHeight - store.height}px` }" style="padding-bottom: 200rpx">
|
||
<view class="item" v-for="(item, index) in shopProductList.productInfo" :key="index"
|
||
:class="{ active: index == leftIndex }" :id="'left-' + index" :data-index="index"
|
||
@click="leftTap(index)">
|
||
<text>{{ item.name }}</text>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
<view class="main">
|
||
<view>
|
||
<view class="item main-item" v-for="(item, index) in shopProductList.productInfo" :key="index"
|
||
:id="'item-' + index">
|
||
<view class="title">
|
||
<view>{{ item.name }}</view>
|
||
</view>
|
||
<view class="goods" @click="clickspecifications(item1, index, index1)"
|
||
v-for="(item1, index1) in item.productList" :key="item1.id">
|
||
<view class="relative">
|
||
<image class="goodsImg" @click.stop="getProductImgs(item1)"
|
||
v-if="item1.coverImg != null" :lazy-load="true"
|
||
:src="`${item1.coverImg}${!item1.imgLoad ? '?x-oss-process=image/resize,m_lfit,w_150,h_150' : ''}`"
|
||
mode="aspectFill"></image>
|
||
<image class="goodsImg"
|
||
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/index/1.gif" mode=""
|
||
v-else :lazy-load="true"></image>
|
||
<view class="limitDiscount" v-if="showLimitDiscount(item1)">
|
||
限时折扣{{ limitDiscountCountdown }}</view>
|
||
|
||
<!-- <view class="limitDiscount" v-if="item1.is_time_discount">
|
||
限时折扣{{ limitDiscountCountdown }}</view> -->
|
||
<view class="stock_warning"
|
||
v-if="item1.isStock&&item1.stockNumber<=10&&item.stockNumber>0">
|
||
仅剩{{item1.stockNumber}}份</view>
|
||
</view>
|
||
|
||
<view class="vifgoodsImg" v-if="
|
||
item1.isSale == 0 ||
|
||
(item1.isSaleTime == 0 && !item1.isSaleTimeshow) ||
|
||
item1.isSoldStock == 1 ||
|
||
(item1.isStock == 1 && item1.stockNumber <= 0)
|
||
">
|
||
<image v-if="item1.isSale == 0" src="@/static/ztt/icon_goods_yxj.svg"
|
||
style="width: 200rpx; height: 100%" mode=""></image>
|
||
<image v-else-if="item1.isSaleTime == 0 && !item1.isSaleTimeshow"
|
||
src="@/static/ztt/icon_goods_wks.svg" style="width: 200rpx; height: 100%"
|
||
mode=""></image>
|
||
<image v-else-if="item1.isSoldStock == 1" src="@/static/ztt/icon_goods_sq.svg"
|
||
style="width: 200rpx; height: 100%" mode=""></image>
|
||
<image v-else-if="item1.isStock == 1 && item1.stockNumber <= 0"
|
||
src="@/static/ztt/icon_goods_kcbz.svg" style="width: 200rpx; height: 100%"
|
||
mode=""></image>
|
||
</view>
|
||
|
||
<view v-if="index == '0'" class="topSort" :class="'c' + (index1 + 1)">
|
||
TOP{{ index1 + 1 }}</view>
|
||
|
||
<view class="goods_right" style="overflow: hidden">
|
||
<view class="name">{{ item1.name }}</view>
|
||
<!-- <view class="lookBack" v-if="index=='0'">本店销量第{{index1+1}}名</view>-->
|
||
<!-- <view class="lookBack" v-if="specifications.item.isHot == 1">热销</view> -->
|
||
<view class="lookBack" v-if="returnIsHot(item1,item,index)">热销</view>
|
||
<view class="describe">{{ item1.shortTitle ? item1.shortTitle : '' }}</view>
|
||
|
||
<view class="describe" v-if="item1.suitNum > 1 && item1.type != 'sku'"
|
||
style="font-size: 20rpx">
|
||
「{{ item1.suitNum }}{{ item1.unitName }}起点」
|
||
</view>
|
||
<view
|
||
v-if="item1.isSoldStock == 1 || (item1.isSaleTime == 0 && !item1.isSaleTimeshow)"
|
||
class="flex-between">
|
||
<view class="money">
|
||
<view>¥</view>
|
||
<text class="money_num" style="margin-right: 10rpx">
|
||
{{ shopUserInfo.isVip == 1 && shopUserInfo.isMemberPrice == 1 ? item1.memberPrice || item1.salePrice : item1.salePrice }}
|
||
</text>
|
||
<text v-if="item1.unitName">/{{ item1.unitName }}</text>
|
||
</view>
|
||
<view class="flex-end">
|
||
<view class="sku-wrap flex-center" style="background-color: #cecece">
|
||
<text class="t"
|
||
v-if="item1.isSaleTime == 0 && !item1.isSaleTimeshow">未开售</text>
|
||
<text class="t" v-else-if="item1.isSoldStock == 1">已售罄</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-else class="flex-between" style="flex-wrap: inherit">
|
||
<view class="money">
|
||
<view>¥</view>
|
||
<view class="money_num">
|
||
<GoodsPrice :limitDiscount="cartStore.limitTimeDiscount" :cart="item1"
|
||
:shopUserInfo="shopUserInfo" :shopInfo="shopInfo"></GoodsPrice>
|
||
</view>
|
||
<text class="money_num" v-if="item1.unitName">/{{ item1.unitName }}</text>
|
||
|
||
<text class="old-price"
|
||
v-if="showLimitDiscount(item1)">¥{{ item1.salePrice }}</text>
|
||
<!-- <text class="old-price"
|
||
v-if="item1.is_time_discount">¥{{ item1.salePrice }}</text> -->
|
||
<!-- <text v-if="item1.suitNum>1 && item1.type!= 'sku'"
|
||
style="font-size: 14rpx;">
|
||
「{{item1.suitNum}}{{item1.unitName}}起点」
|
||
</text> -->
|
||
</view>
|
||
<view class="flex-end"
|
||
v-if="item1.type == 'sku' || (item1.type == 'package' && item1.groupType == '1')">
|
||
<view class="sku-wrap flex-center"
|
||
@click.stop="clickspecifications(item1, index, index1)">
|
||
<text class="t no-wrap" v-if="item1.groupType == '1'">选择套餐</text>
|
||
<text class="t" v-else>选规格</text>
|
||
<!-- <text class="dot num"
|
||
v-if="item1.cartNumber > 0">{{ ifcartNumber(item1) < 99 ? ifcartNumber(item1) : '99+' }}</text> -->
|
||
|
||
<text class="dot num"
|
||
v-if="returnGoodsImCartNum(item1)">{{ returnGoodsImCartNum(item1) < 99 ? returnGoodsImCartNum(item1) : '99+' }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="Controls" v-else>
|
||
<view class="btn" v-if="item1.cartNumber * 1 != '0'">
|
||
<up-icon name="minus-circle-fill" color="#E9AB7A" size="25"></up-icon>
|
||
<!-- <view class="btnClick"
|
||
@tap.stop="$u.throttle(() => singleclick(item1, '-'), 500)"></view> -->
|
||
<view class="btnClick" @tap.stop="singleclick(item1, '-')"></view>
|
||
</view>
|
||
|
||
<text class="num">{{ ifcartNumber(item1) }}</text>
|
||
<view class="btn">
|
||
<up-icon name="plus-circle-fill" color="#E9AB7A" size="25"></up-icon>
|
||
<!-- <view class="btnClick"
|
||
@tap.stop="$u.throttle(() => singleclick(item1, '+'), 500)"></view> -->
|
||
<view class="btnClick" @tap.stop="singleclick(item1, '+')"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="fill-last" :style="{ height: fillHeight + 'px' }"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<confirmorder ref="confirmorderref" :cartLists_count="cartLists_count" :cartList="matchedProducts"
|
||
:totalPrices="totalPrices" :confirmordershow="confirmordershow"
|
||
@close="confirmordershow = !confirmordershow" @customevent="websocketsendMessage" :orderinfo="orderinfo">
|
||
</confirmorder>
|
||
|
||
<!-- 店铺详情 -->
|
||
<shopindex ref="showShopInfoRef"></shopindex>
|
||
<!-- 购物车 -->
|
||
<shoppingCartes :cartLists_count="cartLists_count" :cartList="matchedProducts" :showCart="showCart"
|
||
:limitDiscount="cartStore.limitTimeDiscount" @customevent="websocketsendMessage"
|
||
@close="showCart = !showCart" :orderinfo="orderinfo" @clickcancelOrder="clickcancelOrder"
|
||
v-if="cartLists_count > 0" :nextFullAmountActivty="nextFullAmountActivty"></shoppingCartes>
|
||
|
||
<!-- 显示购物车栏 -->
|
||
<view class="cart-wrap" v-if="cartLists_count > 0 && !confirmordershow && isBusinessTime">
|
||
<view class="cart-content">
|
||
<view class="left">
|
||
<view class="iconBox">
|
||
<image class="icon"
|
||
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/shopDetails/shopIcon.png"
|
||
mode="aspectFill" @click="Historicalorders(true)"></image>
|
||
<text class="u-badge">{{ cartLists_count < 99 ? cartLists_count : '99+' }}</text>
|
||
</view>
|
||
|
||
<text class="i">¥</text>
|
||
<text class="num">{{ actualPrice }}</text>
|
||
|
||
<text class="allDiscountMoney" v-if="allDiscountMoney * 1 > 0">共减¥{{ allDiscountMoney }}</text>
|
||
</view>
|
||
<view class="btn" @tap="$u.debounce(orderdetail, 500)" v-if="orderType == 'scan'">
|
||
<text class="t">结算</text>
|
||
</view>
|
||
<view class="btn" v-else>
|
||
<u-button type="primary" shape="circle" plain @click="beforehandHandle">扫码下单</u-button>
|
||
</view>
|
||
</view>
|
||
<!-- 满减活动 -->
|
||
<view class="fullAmount-activity" v-if="nextFullAmountActivty">
|
||
<text>再买</text>
|
||
<text class="price">
|
||
¥{{
|
||
BigNumber(nextFullAmountActivty.fullAmount)
|
||
.minus(totalPrices * 1)
|
||
.toFixed(2)
|
||
}}
|
||
</text>
|
||
<text>,</text>
|
||
<text>可再减</text>
|
||
<text class="price">¥{{ nextFullAmountActivtyAgignDiscount }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 规格 -->
|
||
<up-popup :show="showShopsku" :round="20" mode="bottom" @close="(showShopsku = false), (pagemetashow = false)">
|
||
<view class="shop_sku">
|
||
<scroll-view scroll-y style="max-height: 60vh; width: 100%">
|
||
<view class="positionabsolute">
|
||
<up-icon name="close-circle" @click="
|
||
showShopsku = false;
|
||
pagemetashow = false;
|
||
" color="#000" size="25"></up-icon>
|
||
</view>
|
||
<up-swiper :list="specifications.item.images" @change="swiperChange" :current="swiperCurrent"
|
||
radius="6px" height="250"
|
||
@click="prveImgs(specifications.item.images, specifications.item.images[swiperCurrent])">
|
||
<!-- <template v-slot:default="{item}">
|
||
<image :src=item></image>
|
||
</templte> -->
|
||
</up-swiper>
|
||
|
||
<view class="shop_sku_name">{{ specifications.item.name }}</view>
|
||
<view class="shop_sku_description" v-if="isSkuGoods">
|
||
{{ specifications.item.shortTitle ? specifications.item.shortTitle : '' }}
|
||
</view>
|
||
<view v-if="specifications.item.type != 'package'">
|
||
<view class="shop_sku_box" v-for="(specOptions, specType) in specifications.item.selectSpecInfo"
|
||
:key="specType">
|
||
<view class="shop_sku_box_name">
|
||
{{ specType }}
|
||
</view>
|
||
<view class="flex-start">
|
||
<view class="shop_sku_box_item" v-for="option in specOptions" :key="option"
|
||
@click="selectSpec(specType, option)" :class="{
|
||
shop_sku_box_item_selected: isSkuSelected(specType, option)
|
||
}">
|
||
{{ option }}
|
||
<view class="shop_sku_box_item_tip"
|
||
v-if="specifications.item.result && specifications.item.result.isSoldStock == 1 && selectedSpecs[specType] === option">
|
||
<view>售罄</view>
|
||
</view>
|
||
<view class="shop_sku_box_item_tip"
|
||
v-if="specifications.item.result == 'kong' && canSubmit == false && selectedSpecs[specType] === option">
|
||
<view>已下架</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 套餐 -->
|
||
<view v-else>
|
||
<view class="shop_sku_box">
|
||
<view v-for="(setmenu, setmenuindex) in specifications.item.groupSnap" :key="setmenuindex">
|
||
<view class="shop_sku_box_name">{{ setmenu.title }} {{ setmenu.count }}
|
||
选{{ setmenu.number }}</view>
|
||
<view class="flex-start">
|
||
<view class="shop_sku_box_item" v-for="(option, goodsid) in setmenu.goods"
|
||
:key="goodsid" @click="goodsidClick(setmenuindex, option, goodsid)" :class="{
|
||
shop_sku_box_item_selected: isOptionSelected(setmenuindex, option)
|
||
}" :disabled="isMaxSelected(setmenuindex) && !isOptionSelected(setmenuindex, option)">
|
||
{{ option.proName }}
|
||
<text v-if="option.unitName">/{{ option.unitName }}</text>
|
||
<view class="shop_sku_box_item_tip" v-if="specifications.item.isSoldStock == 1">
|
||
<view>售罄</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 推荐搭配 -->
|
||
<view class="u-m-t-48 u-p-30">
|
||
<view class="font-bold u-font-32 ">推荐搭配</view>
|
||
<view class="u-flex recommand-goods">
|
||
<view class=" item" v-for="(item,index) in 6" :key="index">
|
||
<up-image width="210rpx" height="210rpx" radius="12rpx"></up-image>
|
||
<view class="info">
|
||
<view class="u-line-2 name u-m-t-10 u-font-32 font-500">
|
||
商品名
|
||
</view>
|
||
|
||
<view class="u-flex u-row-between">
|
||
<view class="font-bold">
|
||
<text class="u-font-24">¥</text>
|
||
<text class="u-font-32">40</text>
|
||
</view>
|
||
<view class="btn">
|
||
<up-icon name="plus-circle-fill" color="#E9AB7A" size="25"></up-icon>
|
||
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
|
||
|
||
</view>
|
||
</view>
|
||
|
||
|
||
</view>
|
||
</scroll-view>
|
||
<!-- 占位 -->
|
||
<view class="shop_bottom">
|
||
<view class="flex-between">
|
||
<view class="price price-sku"
|
||
v-if="specifications.item.type != 'package' && specifications.item.result">
|
||
<text class="i">¥</text>
|
||
<view class="num">
|
||
<GoodsPrice :limitDiscount="cartStore.limitTimeDiscount"
|
||
:cart="specifications.item.result" :shopUserInfo="shopUserInfo"
|
||
:shopInfo="shopInfo"></GoodsPrice>
|
||
</view>
|
||
|
||
<text class="num" v-if="false">
|
||
{{
|
||
shopUserInfo.isVip == 1 && shopUserInfo.isMemberPrice == 1
|
||
? specifications.item.result.memberPrice || specifications.item.result.salePrice
|
||
: specifications.item.result.salePrice
|
||
}}
|
||
</text>
|
||
<text class="i"
|
||
v-if="specifications.item.unitName">/{{ specifications.item.unitName }}</text>
|
||
<text
|
||
v-if="specifications.item.result.suitNum > 1">「{{ specifications.item.result.suitNum }}{{ specifications.item.result.unitName }}起点」</text>
|
||
</view>
|
||
<view class="price price-package" v-else>
|
||
<text class="i">¥</text>
|
||
<view class="num">
|
||
<GoodsPrice :limitDiscount="cartStore.limitTimeDiscount" :cart="specifications.item"
|
||
:shopUserInfo="shopUserInfo" :shopInfo="shopInfo"></GoodsPrice>
|
||
</view>
|
||
<text class="num" v-if="false">
|
||
{{
|
||
shopUserInfo.isVip == 1 && shopUserInfo.isMemberPrice == 1
|
||
? specifications.item.memberPrice || specifications.item.salePrice
|
||
: specifications.item.salePrice
|
||
}}
|
||
</text>
|
||
<text class="i"
|
||
v-if="specifications.item.unitName">/{{ specifications.item.unitName }}</text>
|
||
<text
|
||
v-if="specifications.item.suitNum > 1">「{{ specifications.item.suitNum }}{{ specifications.item.unitName }}起点」</text>
|
||
</view>
|
||
|
||
<view class="operation-wrap"
|
||
v-if="specifications.item.type != 'package'&&stockNumberIsFull(specifications.item)">
|
||
<view class="btn">
|
||
<up-icon name="minus-circle-fill" color="#E9AB7A" size="25"
|
||
v-if="shopCartNumber > 0"></up-icon>
|
||
<view class="btnClick" @click="shopCart('-')"></view>
|
||
</view>
|
||
<text class="num">{{ shopCartNumber }}</text>
|
||
<view class="btn">
|
||
<up-icon name="plus-circle-fill" color="#E9AB7A" size="25"></up-icon>
|
||
<view class="btnClick" @click="shopCart('+')"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="shop_skuselect flex-start" v-if="selectedSpecsStr">
|
||
<view class="shop_skuselectname">{{ selectedSpecsStr }}</view>
|
||
</view>
|
||
<template v-if="!stockNumberIsFull(specifications.item)">
|
||
<view class="addShopping">
|
||
库存不足
|
||
</view>
|
||
</template>
|
||
<template v-else>
|
||
<template v-if="isSkuGoods">
|
||
<view v-if="specifications.item.type == 'package'" class="addShopping"
|
||
:class="shopCartNumber > 0 && allConditionsSatisfied ? 'active' : ''"
|
||
@click="submitSelection()">
|
||
{{ skuBtnText }}
|
||
</view>
|
||
<view v-else class="addShopping" :class="shopCartNumber > 0 && canSubmit ? 'active' : ''"
|
||
@click="submitSelection()">
|
||
{{ skuBtnText }}
|
||
</view>
|
||
</template>
|
||
<template v-else>
|
||
<view class="addShopping" :class="shopCartNumber > 0 ? 'active' : ''"
|
||
@click="submitSelection()">
|
||
{{ skuBtnText }}
|
||
</view>
|
||
</template>
|
||
</template>
|
||
|
||
|
||
</view>
|
||
</view>
|
||
</up-popup>
|
||
<view class="history_order" @click="toHistory"
|
||
v-if="shopInfo && shopInfo.registerType == 'after' && orderinfo.id">
|
||
<image class="img" src="@/static/history.png" mode=""></image>
|
||
<text>已下单菜品</text>
|
||
</view>
|
||
<Loading :isLoading="!useSocket.isConnected" />
|
||
<ModalList></ModalList>
|
||
<recommendGoodsModal v-if="isDataLoaded" @onBuyClick="onBuyClick"></recommendGoodsModal>
|
||
|
||
<view
|
||
v-for="(item,index) in goodsModalList" :key="index"
|
||
>
|
||
<goodsModal :key="index" v-model="item.show" :goods="item.goods" @prveImgs="prveImgs" @close="goodsModalClose(index)"
|
||
@websocketsendMessage="websocketsendMessage"
|
||
@modalAdd="modalAdd"
|
||
:GoodsIDInCartNumMap="GoodsIDInCartNumMap"
|
||
></goodsModal>
|
||
</view>
|
||
|
||
<xbSwiperPreview :visable="showPrveImg" :imgs="prveImgsList" @update:visable="updateShowPrveImg">
|
||
</xbSwiperPreview>
|
||
<!-- 显示选择人数popup -->
|
||
<u-popup mode="bottom" :safe-area-inset-bottom="false" :show="showTableInfoPeopleNumPopup">
|
||
<view class="select_num_wrap">
|
||
<image class="top_bg" src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/order/orderAMeal.png"
|
||
mode="aspectFill"></image>
|
||
<view class="sn-bnottom">
|
||
<view class="sn-header">
|
||
<text class="t1">请选择就餐人数</text>
|
||
<text class="t2">桌号{{ shopTable.name }}</text>
|
||
</view>
|
||
<view class="sn-num-wrap">
|
||
<view class="sn-num">
|
||
<view class="item" :class="{ active: tableInfoPeopleActive == index }"
|
||
v-for="(item, index) in 10" :key="item" @click="tableInfoPeopleNumHandle(item, index)">
|
||
<text class="t">{{ item }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="input">
|
||
<u-input v-model="tableInfoPeopleNum" :maxlength="2" placeholder="请输入自定义人数" clearable
|
||
@change="tableInfoPeopleNumInput"></u-input>
|
||
</view>
|
||
</view>
|
||
<view class="sn-footer-wrap">
|
||
<view class="btn">
|
||
<u-button plain shape="circle" size="large" @click="closeTableInfoPeopleNum">取消</u-button>
|
||
</view>
|
||
<view class="btn">
|
||
<u-button type="primary" size="large" shape="circle"
|
||
@click="tableInfoPeopleNumConfirm">确认</u-button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</u-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
/**
|
||
* api合集 start
|
||
*/
|
||
import * as discountActivityApi from '@/common/api/market/discountActivity';
|
||
import {
|
||
consumeDiscount
|
||
} from '@/common/api/market/index.js';
|
||
import * as limitTimeDiscountapi from '@/common/api/market/limitTimeDiscount.js';
|
||
import {
|
||
APIshopUserInfo,
|
||
APIusershopInfodetail
|
||
} from "@/common/api/member.js";
|
||
|
||
import {
|
||
productminiApphotsquery,
|
||
APIgroupquery,
|
||
APIminiAppinfo,
|
||
APIminiAppskuinfo,
|
||
productRelated
|
||
} from '@/common/api/product/product.js';
|
||
|
||
import {
|
||
APIhistoryOrder,
|
||
APIcancelOrder,
|
||
APIrmPlaceOrder
|
||
} from '@/common/api/order/index.js';
|
||
import {
|
||
APIproductqueryShop
|
||
} from '@/common/api/member.js';
|
||
/**
|
||
* api合集 end
|
||
*/
|
||
|
||
/**
|
||
* 三方库 start
|
||
*/
|
||
import BigNumber from 'bignumber.js';
|
||
//价格计算辅助函数
|
||
import {
|
||
limitUtils
|
||
} from 'ysk-utils';
|
||
|
||
import dayjs from 'dayjs';
|
||
import isBetween from 'dayjs/plugin/isBetween';
|
||
dayjs.extend(isBetween);
|
||
/**
|
||
* 三方库 end
|
||
*/
|
||
|
||
/**
|
||
* 组件 start
|
||
*/
|
||
|
||
import xbSwiperPreview from '@/components/xb-swiper-preview/index.vue';
|
||
import GoodsPrice from '@/components/goods-price.vue';
|
||
import ModalList from '@/components/modal-list.vue';
|
||
import recommendGoodsModal from './components/recommend-goods-modal.vue';
|
||
//导航栏
|
||
import Nav from '@/components/CustomNavbar.vue';
|
||
import shopindex from './components/shopindex.vue';
|
||
import goodsModal from './components/goods-modal.vue';
|
||
import shoppingCartes from './components/shoppingCartes.vue';
|
||
import confirmorder from './components/confirmorder.vue';
|
||
import Loading from '@/components/Loading.vue';
|
||
/**
|
||
* 组件 end
|
||
*/
|
||
|
||
|
||
/**
|
||
* 项目代码辅助方法 start
|
||
*/
|
||
import {
|
||
filterNumberInput,
|
||
isJsonArrayString
|
||
} from '@/utils/util.js';
|
||
import {
|
||
getDistance
|
||
} from '@/utils/address.js';
|
||
import {
|
||
isObjectEqual,
|
||
isArrayEqual
|
||
} from './components/utils.js'
|
||
/**
|
||
* 项目代码辅助方法 end
|
||
*/
|
||
|
||
|
||
/**
|
||
* store本地存储 start
|
||
*/
|
||
|
||
import {
|
||
useNavbarStore
|
||
} from '@/stores/navbarStore';
|
||
|
||
|
||
import {
|
||
useWebSocket
|
||
} from '@/stores/carts-websocket.js';
|
||
// 结账管理
|
||
import {
|
||
Memberpay
|
||
} from '@/stores/pay.js';
|
||
import {
|
||
productStore
|
||
} from '@/stores/user.js';
|
||
|
||
const storeMemberpay = Memberpay();
|
||
const store = useNavbarStore();
|
||
// 动态更新导航栏配置
|
||
store.updateNavbarConfig({
|
||
showBack: true, //左边返回键
|
||
rightText: '', //右边文字
|
||
showSearch: false, //true是标题其他事文字
|
||
title: '',
|
||
isTransparent: false,
|
||
hasPlaceholder: false //是否要占位符
|
||
});
|
||
const userStore = productStore();
|
||
// 金额管理
|
||
import {
|
||
useCartStore
|
||
} from '@/stores/order.js';
|
||
import {
|
||
computed, provide
|
||
} from 'vue';
|
||
const cartStore = useCartStore();
|
||
/**
|
||
* store本地存储 end
|
||
*/
|
||
|
||
// 获取全局属性
|
||
const {
|
||
proxy
|
||
} = getCurrentInstance();
|
||
|
||
//点单智能推荐
|
||
function onBuyClick(item) {
|
||
let index = -1;
|
||
let index1 = -1;
|
||
if (!item.isHot) {
|
||
if (item.type == 'sku' || (item.type == 'package' && item.groupType == '1')) {
|
||
for (let i in shopProductList.productInfo) {
|
||
const cate = shopProductList.productInfo[i];
|
||
const goodsList = cate.productList;
|
||
const index1 = goodsList.findIndex((goods) => goods.id == item.id);
|
||
if (index1 > -1) {
|
||
index = i;
|
||
clickspecifications(item, index, index1);
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
uni.$u.throttle(() => singleclick(item, '+'), 500);
|
||
}
|
||
} else {
|
||
if (item.type == 'sku' || (item.type == 'package' && item.groupType == '1')) {
|
||
for (let i in shopProductList.hots) {
|
||
const goods = shopProductList.hots[i];
|
||
if (goods.id == item.id) {
|
||
index = i;
|
||
clickspecifications(item, index, index);
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
uni.$u.throttle(() => singleclick(item, '+'), 500);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 通用数据合集 start
|
||
*/
|
||
|
||
// 门店信息
|
||
const shopInfo = reactive({});
|
||
Object.assign(shopInfo, uni.cache.get('shopInfo'));
|
||
// 台桌信息
|
||
const shopTable = uni.cache.get('shopTable');
|
||
//距离
|
||
const distance = uni.cache.get('distance');
|
||
|
||
//店铺详情
|
||
const showShopInfoRef = ref(null);
|
||
// 计算高度
|
||
const navScroll = ref(null);
|
||
|
||
// 初始加载中
|
||
const isLoading = ref(true);
|
||
|
||
|
||
|
||
// 分步取值 + 每层兜底,避免某一环不存在导致 undefined
|
||
const shopExtendShopTable = uni.cache.get('shopTable') || {}; // 兜底空对象
|
||
const shopExtendMap = shopExtendShopTable.shopExtendMap || {}; // 兜底空对象
|
||
// 最终声明:即使 shopinfo_bg 不存在,也兜底为空字符串/默认值
|
||
const shopExtend = ref(shopExtendMap.shopinfo_bg || '');
|
||
|
||
/**
|
||
* 通用数据合集 end
|
||
*/
|
||
|
||
|
||
/**
|
||
* 轮播功能 staart
|
||
*/
|
||
const swiperCurrent = ref(0);
|
||
|
||
function swiperChange(e) {
|
||
swiperCurrent.value = e.current;
|
||
}
|
||
/**
|
||
* 轮播功能 end
|
||
*/
|
||
|
||
|
||
//调用shop组件
|
||
const callChildMethod = () => {
|
||
if (showShopInfoRef.value) {
|
||
showShopInfoRef.value.childMethod();
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// 购物车对应的商品数
|
||
const GoodsIDInCartNumMap = computed(() => {
|
||
const map = {}
|
||
for (let cart of cartStore.carts) {
|
||
if (map[cart.product_id]) {
|
||
map[cart.product_id] += cart.number * 1
|
||
} else {
|
||
map[cart.product_id] = cart.number * 1
|
||
}
|
||
|
||
}
|
||
return map
|
||
})
|
||
|
||
/**
|
||
* 返回购物车对应的商品数量
|
||
*/
|
||
function returnGoodsImCartNum(goods) {
|
||
if(!goods){
|
||
return 0
|
||
}
|
||
if (GoodsIDInCartNumMap.value.hasOwnProperty(goods.id)) {
|
||
GoodsIDInCartNumMap.value[goods.id]
|
||
}
|
||
return 0
|
||
}
|
||
|
||
|
||
// 获取商品数据
|
||
const shopProductList = reactive({
|
||
hots: [],
|
||
productInfo: []
|
||
});
|
||
|
||
|
||
|
||
// 计算左侧位置
|
||
const leftIndex = ref(0);
|
||
|
||
//元素最低端的距离
|
||
const lastbottom = ref('');
|
||
|
||
//储存元素的下标
|
||
const topArr = ref([]);
|
||
|
||
// 填充高度,用于最后一项低于滚动区域时使用
|
||
const fillHeight = ref(200);
|
||
|
||
//距离顶部的高度
|
||
const scrollTopSize = ref(0);
|
||
|
||
//左侧导航点击
|
||
const leftTap = (index) => {
|
||
uni.pageScrollTo({
|
||
scrollTop: topArr.value[index] - store.height,
|
||
duration: 0
|
||
});
|
||
leftIndex.value = index;
|
||
};
|
||
|
||
/* 计算左侧滚动位置定位 */
|
||
const leftIntoView = computed(() => {
|
||
return `left-${leftIndex.value ? leftIndex.value : 0}`;
|
||
});
|
||
|
||
/* 获取元素顶部信息 */
|
||
const getElementTop = () => {
|
||
new Promise((resolve, reject) => {
|
||
let view = uni.createSelectorQuery().selectAll('.main-item');
|
||
view.boundingClientRect(async (data) => {
|
||
resolve(data);
|
||
}).exec();
|
||
proxy.$uGetRect('.scroll-panel').then((res) => {
|
||
scrollTopSize.value = res.top; //元素距离顶部的距离
|
||
});
|
||
}).then((res) => {
|
||
try {
|
||
topArr.value = res.map((item) => {
|
||
return item.top; /* 减去滚动容器距离顶部的距离 加导航栏高度*/
|
||
});
|
||
|
||
// 获取最后一个元素最低端的盒子到顶点的距离
|
||
for (let i = 0; i <= topArr.value.length - 1; i++) {
|
||
if (store.screenHeight - 200 >= topArr.value[topArr.value.length - 1] - topArr.value[i]) {
|
||
// 获取距离最后一个index
|
||
lastbottom.value = i;
|
||
break;
|
||
}
|
||
}
|
||
/* 获取最后一项的高度,设置填充高度。判断和填充时做了 +-20 的操作,是为了滚动时更好的定位 */
|
||
let last = res[res.length - 1].height;
|
||
if (last - 20 < store.screenHeight) {
|
||
fillHeight.value = 200;
|
||
}
|
||
} catch (error) {
|
||
//TODO handle the exception
|
||
}
|
||
});
|
||
};
|
||
|
||
// 定时器
|
||
const mainThrottle = ref(null);
|
||
|
||
/* 主区域滚动监听 */
|
||
const mainScroll = (e) => {
|
||
// 节流方法
|
||
clearTimeout(mainThrottle.value);
|
||
mainThrottle.value = setTimeout(() => {
|
||
scrollFn();
|
||
}, 10);
|
||
let scrollFn = () => {
|
||
let top = e.scrollTop;
|
||
let index = 0;
|
||
// 判断左边是否可以滑动
|
||
|
||
for (let i = topArr.value.length - 1; i >= 0; i--) {
|
||
/* 在部分安卓设备上,因手机逻辑分辨率与rpx单位计算不是整数,滚动距离与有误差,增加2px来完善该问题 */
|
||
if (top + 2 >= topArr.value[i] - store.height) {
|
||
index = i;
|
||
break;
|
||
}
|
||
}
|
||
/* 查找当前滚动距离 */
|
||
if (index >= lastbottom.value) {
|
||
//
|
||
leftIndex.value = index > leftIndex.value ? index : leftIndex.value;
|
||
// this.leftIndex = this.leftIndex
|
||
} else {
|
||
leftIndex.value = index < 0 ? 0 : index;
|
||
}
|
||
};
|
||
};
|
||
|
||
//动态导航栏滑动距离
|
||
onPageScroll((res) => {
|
||
uni.$u.debounce((store.scrollTop = res.scrollTop), 500);
|
||
uni.$u.debounce((navScroll.value = res.scrollTop), 500);
|
||
uni.$u.debounce(mainScroll(res), 500);
|
||
});
|
||
|
||
// 点击详情
|
||
const showShopsku = ref(false);
|
||
|
||
// 规格信息
|
||
const specifications = reactive({
|
||
item: {},
|
||
index: '',
|
||
inedxs: '',
|
||
type: '',
|
||
product_id: '',
|
||
sku_id: '',
|
||
groupSnap: {},
|
||
item: {
|
||
groupSnap: [],
|
||
result: {
|
||
isSoldStock: 0
|
||
}
|
||
}
|
||
});
|
||
// 用于判断接口数据是否加载完成
|
||
const isDataLoaded = ref(false);
|
||
|
||
// 存储用户当前选择的规格,初始为空对象
|
||
const selectedSpecs = ref({});
|
||
|
||
// 能否提交的状态
|
||
const canSubmit = ref(false);
|
||
|
||
//字形判断
|
||
const skuBtnText = ref('添加到购物车');
|
||
|
||
// 计算属性,判断是否所有规格类型都有选中项
|
||
const allSpecsSelected = computed(() => {
|
||
// 获取所有规格类型的键
|
||
const specKeys = Object.keys(specifications.item.selectSpecInfo);
|
||
// skuBtnText.value = selectedSpecsStr.value ? `您还没选择${specKeys[1]}哦` : ``
|
||
// 检查每个规格类型是否都在 selectedSpecs 中有对应的选中值
|
||
return specKeys.every((key) => selectedSpecs.value[key]);
|
||
});
|
||
|
||
function isSkuSelected(specType, option) {
|
||
return selectedSpecs.value[specType] === option;
|
||
}
|
||
|
||
// 处理规格选择的方法
|
||
const selectSpec = async (specType, option) => {
|
||
// 规格清零
|
||
shopCartNumber.value = 0;
|
||
|
||
// 更新 selectedSpecs 对象,将当前规格类型的选中值设置为用户点击的选项
|
||
const newSelectedSpecs = {};
|
||
const specKeys = Object.keys(specifications.item.selectSpecInfo);
|
||
for (const key of specKeys) {
|
||
if (key === specType) {
|
||
newSelectedSpecs[key] = option;
|
||
} else {
|
||
newSelectedSpecs[key] = selectedSpecs.value[key];
|
||
}
|
||
}
|
||
selectedSpecs.value = newSelectedSpecs;
|
||
if (allSpecsSelected.value) {
|
||
// try {
|
||
let result = await APIminiAppskuinfo({
|
||
specInfo: selectedSpecsStr.value,
|
||
id: specifications.item.id
|
||
});
|
||
// skuList
|
||
if (result != true) {
|
||
specifications.sku_id = result.id;
|
||
specifications.product_id = result.productId;
|
||
// 添加多规格分组
|
||
specifications.item.result = result;
|
||
if (result.isSoldStock == 0) {
|
||
canSubmit.value = true;
|
||
} else {
|
||
canSubmit.value = false;
|
||
}
|
||
} else {
|
||
specifications.item.result = 'kong';
|
||
canSubmit.value = false;
|
||
}
|
||
} else {
|
||
canSubmit.value = false;
|
||
}
|
||
};
|
||
|
||
const shopUserInfo = ref(uni.cache.get('shopUserInfo'));
|
||
|
||
// 监听 specifications 的变化
|
||
watch(
|
||
() => specifications.item.groupSnap,
|
||
(newGroupSnap) => {
|
||
if (Array.isArray(newGroupSnap)) {
|
||
selectedOptions.value = newGroupSnap.map(() => []);
|
||
}
|
||
}
|
||
);
|
||
|
||
// 存储选中的选项,二维数组
|
||
const selectedOptions = ref(specifications.item.groupSnap.map(() => []));
|
||
|
||
// / 选择规格的方法
|
||
const goodsidClick = (setmenuindex, option, goodsid) => {
|
||
if (!selectedOptions.value[setmenuindex]) {
|
||
// 如果 selectedOptions.value[setmenuindex] 不存在,初始化一个空数组
|
||
selectedOptions.value[setmenuindex] = [];
|
||
}
|
||
if (isOptionSelected(setmenuindex, option)) {
|
||
// 如果已经选中,取消选中
|
||
selectedOptions.value[setmenuindex] = selectedOptions.value[setmenuindex].filter((item) => item.proId !==
|
||
option.proId);
|
||
} else if (!isMaxSelected(setmenuindex)) {
|
||
// 如果未达到最大选择数量,添加到选中列表
|
||
selectedOptions.value[setmenuindex].push(option);
|
||
}
|
||
};
|
||
|
||
// 判断选项是否已选中
|
||
const isOptionSelected = (setmenuindex, option) => {
|
||
// 确保 selectedOptions.value[setmenuindex] 存在
|
||
if (selectedOptions.value[setmenuindex]) {
|
||
return selectedOptions.value[setmenuindex].some((item) => item.proId === option.proId);
|
||
}
|
||
return false;
|
||
};
|
||
|
||
// 判断是否达到最大选择数量
|
||
const isMaxSelected = (setmenuindex) => {
|
||
// 确保 selectedOptions.value[setmenuindex] 存在
|
||
if (selectedOptions.value[setmenuindex]) {
|
||
return selectedOptions.value[setmenuindex].length >= specifications.item.groupSnap[setmenuindex].number;
|
||
}
|
||
return false;
|
||
};
|
||
|
||
// 计算所有选中条件是否都符合
|
||
const allConditionsSatisfied = computed(() => {
|
||
// 检查 specifications.item.groupSnap 是否存在
|
||
if (!specifications.item?.groupSnap) {
|
||
return false;
|
||
}
|
||
return specifications.item.groupSnap.every((optionGroup, index) => {
|
||
// 获取当前索引对应的已选选项,如果不存在则默认为空数组
|
||
const selected = selectedOptions.value[index] || [];
|
||
// 检查是否达到最大选择数量
|
||
const hasEnoughSelection = selected.length === optionGroup.number;
|
||
return hasEnoughSelection;
|
||
});
|
||
});
|
||
|
||
// 提交选择,套餐选中最后处理的数据
|
||
const selectedGroupSnap = ref([]);
|
||
|
||
// 计算属性,将 selectedSpecs 转换为字符串形式
|
||
const selectedSpecsStr = computed(() => {
|
||
const values = Object.values(selectedSpecs.value);
|
||
return values.join(',');
|
||
});
|
||
|
||
//添加购物车数量
|
||
const shopCartNumber = ref(0);
|
||
|
||
// 多规格 套餐 单规格添加数量
|
||
const shopCart = async (i) => {
|
||
if (i == '-' && shopCartNumber.value <= (specifications.item.suitNum || 1)) {
|
||
shopCartNumber.value = 0;
|
||
return false;
|
||
}
|
||
let res = await shoppingcart();
|
||
// if (!isSkuGoods.value) {
|
||
// console.log("specifications.item", specifications.item);
|
||
// if (i == "-") {
|
||
// shopCartNumber.value--;
|
||
// } else {
|
||
// shopCartNumber.value++;
|
||
// }
|
||
// specifications.item.cartNumber = shopCartNumber.value;
|
||
// singleclick(specifications.item, i);
|
||
// return;
|
||
// }
|
||
if (specifications.item.result === 'kong') {
|
||
//没有满足可添加或者编辑的规格
|
||
return;
|
||
}
|
||
if (i == '-') {
|
||
if (!res && shopCartNumber.value == specifications.item.suitNum) {
|
||
uni.showToast({
|
||
title: `起点${specifications.item.suitNum}个`,
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
} else {
|
||
shopCartNumber.value--;
|
||
}
|
||
} else {
|
||
if (!res && shopCartNumber.value < 1) {
|
||
if (specifications.type == 'sku') {
|
||
shopCartNumber.value = parseFloat(specifications.item.result.suitNum);
|
||
} else {
|
||
shopCartNumber.value = parseFloat(specifications.item.suitNum);
|
||
}
|
||
} else {
|
||
shopCartNumber.value++;
|
||
}
|
||
}
|
||
};
|
||
|
||
//返回是否是热销商品
|
||
function returnIsHot(item, category, index) {
|
||
return item.isHot && category.name == '热销' && index == 0 && shopProductList.hots.find(v => v.id == item.id)
|
||
}
|
||
|
||
|
||
|
||
// 根据购物车的数据匹配选中的商品查找是否有匹配的数组
|
||
const matchingProduct = async (data) => {
|
||
return matchedProducts.value.find((product, index) => {
|
||
if (specifications.type == 'package') {
|
||
// 套餐
|
||
let result = false;
|
||
try {
|
||
if (product.type == 'package') {
|
||
let res = JSON.parse(product.cartListinfo.pro_group_info);
|
||
result = isArrayEqual(res, selectedGroupSnap.value);
|
||
}
|
||
} catch (error) {
|
||
//TODO handle the exception
|
||
}
|
||
// 直接返回布尔值
|
||
return result;
|
||
} else if (specifications.item.type == 'sku') {
|
||
// 多规格
|
||
return product.cartListinfo.sku_id == data.id && product.cartListinfo.product_id == data
|
||
.productId;
|
||
} else {
|
||
// 其他
|
||
return product.skuId == data.skuId && product.id == data.id;
|
||
}
|
||
});
|
||
};
|
||
|
||
// 判断多规格和套餐 商品是否在购物车有数据
|
||
const shoppingcart = async () => {
|
||
let res = null;
|
||
if (specifications.item.type == 'package') {
|
||
if (!allConditionsSatisfied.value) {
|
||
return false;
|
||
}
|
||
// 是否是套餐package
|
||
selectedGroupSnap.value = specifications.item.groupSnap.map((setmenu, index) => {
|
||
return {
|
||
...setmenu,
|
||
goods: selectedOptions.value[index]
|
||
};
|
||
});
|
||
res = await matchingProduct(selectedGroupSnap.value);
|
||
} else if (specifications.item.type == 'sku') {
|
||
if (!canSubmit.value) {
|
||
return false;
|
||
}
|
||
res = await matchingProduct(specifications.item.result);
|
||
} else {
|
||
// 单规格
|
||
res = await matchingProduct(specifications.item);
|
||
}
|
||
return res;
|
||
};
|
||
|
||
// 提交选择并执行下一步操作的方法
|
||
const submitSelection = async () => {
|
||
if (!isProductAvailable(specifications.productListitem.days, specifications.productListitem.startTime,
|
||
specifications.productListitem.endTime)) {
|
||
uni.showToast({
|
||
title: '不在可售时间内'
|
||
});
|
||
return false;
|
||
}
|
||
// 判断购物车是否有该选中商品
|
||
// 数量不能少于0
|
||
if (shopCartNumber.value <= 0) {
|
||
return;
|
||
}
|
||
let res = await shoppingcart();
|
||
|
||
if ((specifications.item.type == 'package' && allConditionsSatisfied.value) || (specifications.item.type ==
|
||
'sku' && canSubmit.value)) {
|
||
// 是否是套餐 有就传
|
||
if (specifications.item.type == 'package') {
|
||
// 需求更改:所所有商品套餐都是add,没有修改
|
||
res = null;
|
||
} else {
|
||
selectedGroupSnap.value = [];
|
||
}
|
||
console.log('specifications.item', specifications.item);
|
||
websocketsendMessage({
|
||
id: res ? res.cartListId : '',
|
||
type: 'shopping',
|
||
suitNum: specifications.productListitem.suitNum,
|
||
table_code: uni.cache.get('tableCode'),
|
||
shop_id: uni.cache.get('shopId'),
|
||
operate_type: res ? 'edit' : 'add',
|
||
product_id: specifications.product_id,
|
||
sku_id: specifications.sku_id,
|
||
number: res ? await calculateValue(res.cartNumber, '+', shopCartNumber.value) :
|
||
shopCartNumber.value,
|
||
pro_group_info: selectedGroupSnap.value,
|
||
goods_type: specifications.item.type == 'package' ? 'package' : '',
|
||
memberPrice: specifications.item.memberPrice,
|
||
is_print: 1,
|
||
product_type: specifications.item.type,
|
||
is_time_discount: showLimitDiscount(specifications.item)
|
||
});
|
||
// 清空套餐选中
|
||
selectedGroupSnap.value = [];
|
||
showShopsku.value = false;
|
||
} else {
|
||
websocketsendMessage({
|
||
id: res ? res.cartListId : '',
|
||
type: 'shopping',
|
||
suitNum: specifications.productListitem.suitNum,
|
||
table_code: uni.cache.get('tableCode'),
|
||
shop_id: uni.cache.get('shopId'),
|
||
operate_type: res ? 'edit' : 'add',
|
||
product_id: specifications.product_id,
|
||
sku_id: specifications.sku_id,
|
||
number: res ? await calculateValue(res.cartNumber, '+', shopCartNumber.value) :
|
||
shopCartNumber.value,
|
||
memberPrice: specifications.item.memberPrice,
|
||
is_print: 1,
|
||
product_type: specifications.item.type,
|
||
is_time_discount: showLimitDiscount(specifications.item)
|
||
});
|
||
showShopsku.value = false;
|
||
|
||
return;
|
||
}
|
||
};
|
||
|
||
//返回是否是多规格商品
|
||
function returnIsSkuGoods(item) {
|
||
if (item.type == 'single' || item.type == 'weight' || (item.type == 'package' && item.groupType == '0')) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
const isSkuGoods = computed(() => {
|
||
return returnIsSkuGoods(specifications.item);
|
||
});
|
||
|
||
//预览图
|
||
const showPrveImg = ref(false);
|
||
const prveImgsList = ref([]);
|
||
|
||
function updateShowPrveImg(e) {
|
||
showPrveImg.value = e
|
||
}
|
||
|
||
function prveImgs(images) {
|
||
prveImgsList.value = images;
|
||
showPrveImg.value = true;
|
||
return;
|
||
uni.previewImage({
|
||
urls: images,
|
||
current: swiperCurrent.value
|
||
});
|
||
}
|
||
|
||
async function getProductImgs(item) {
|
||
console.log('getProductImgs', item)
|
||
let res = await APIminiAppinfo(item.id);
|
||
prveImgs(res.images);
|
||
}
|
||
|
||
const goodsModalList=ref([])
|
||
|
||
function goodsModalClose(index){
|
||
goodsModalList.value.splice(index,1)
|
||
}
|
||
function modalAdd(item){
|
||
clickspecifications(item)
|
||
}
|
||
|
||
//获取多规格数据
|
||
const clickspecifications = async (item, index, indexs, type) => {
|
||
console.log('clickspecifications', item);
|
||
// 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券
|
||
// if (
|
||
// item.isSoldStock == 1 ||
|
||
// (item.isSaleTime == 0 && !item.isSaleTimeshow) ||
|
||
// item.type == "single" ||
|
||
// item.type == "weight" ||
|
||
// (item.type == "package" && item.groupType == "0")
|
||
// ) {
|
||
// return false;
|
||
// }
|
||
|
||
if (item.isSoldStock == 1 || (item.isSaleTime == 0 && !item.isSaleTimeshow)) {
|
||
return uni.showToast({
|
||
title:'商品已下架或不在可售时间内',
|
||
icon:'none'
|
||
});
|
||
}
|
||
|
||
shopCartNumber.value = 0;
|
||
|
||
// 数量清零
|
||
// 初始化
|
||
let data = {
|
||
item: item,
|
||
productListitem: item,
|
||
type: '',
|
||
product_id: '',
|
||
sku_id: ''
|
||
};
|
||
Object.assign(specifications, data);
|
||
// 初始化 多规格选中
|
||
selectedSpecs.value = {};
|
||
canSubmit.value = false;
|
||
// skuBtnText.value = '请选择规格'
|
||
// single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券
|
||
let res = await APIminiAppinfo(item.id);
|
||
|
||
console.log('res', res);
|
||
console.log('item', item);
|
||
specifications.item = {
|
||
...res,
|
||
...item,
|
||
product_id: res.id,
|
||
sku_id: item.skuId
|
||
};
|
||
if (specifications.item.type == 'package') {
|
||
selectedOptions.value = [];
|
||
specifications.product_id = res.id;
|
||
specifications.sku_id = item.skuId;
|
||
shopCartNumber.value = 1;
|
||
} else {
|
||
specifications.product_id = res.id || specifications.item.product_id;
|
||
specifications.sku_id = item.skuId || specifications.item.sku_id;
|
||
}
|
||
// 购物车是否有商品
|
||
specifications.type = res.type;
|
||
specifications.item.selectSpecInfo = Object.fromEntries(Object.entries(specifications.item.selectSpecInfo)
|
||
.filter(([_, value]) => value.length > 0));
|
||
// 给默认数量
|
||
specifications.item.amountcartNumber = 0;
|
||
// showShopsku.value = true;
|
||
goodsModalList.value.push({
|
||
show:true,
|
||
goods:specifications.item
|
||
})
|
||
};
|
||
// 判断商品是否在可售时间内
|
||
const isProductAvailable = async (sellDaysStr, startTimeStr, endTimeStr) => {
|
||
// 将后端返回的字符串转换为数组
|
||
const sellDays = sellDaysStr.split(',');
|
||
const now = dayjs();
|
||
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
||
const currentDay = days[now.day()];
|
||
|
||
// console.log('当前日期:', currentDay);
|
||
// console.log('可售日期列表:', sellDays);
|
||
|
||
// 检查当前周几是否在可售周几列表中
|
||
if (!sellDays.includes(currentDay)) {
|
||
// console.log('当前日期不在可售日期列表中');
|
||
return false;
|
||
}
|
||
|
||
const startTime = dayjs(`${now.format('YYYY-MM-DD')} ${startTimeStr}`);
|
||
let endTime = dayjs(`${now.format('YYYY-MM-DD')} ${endTimeStr}`);
|
||
|
||
// 处理跨天情况
|
||
if (endTime.isBefore(startTime)) {
|
||
endTime = endTime.add(1, 'day');
|
||
}
|
||
|
||
// console.log('当前时间:', now.format('YYYY-MM-DD HH:mm:ss'));
|
||
// console.log('开始时间:', startTime.format('YYYY-MM-DD HH:mm:ss'));
|
||
// console.log('结束时间:', endTime.format('YYYY-MM-DD HH:mm:ss'));
|
||
|
||
const isInRange = now.isBetween(startTime, endTime, null, '[)');
|
||
// console.log('当前时间是否在可售时间范围内:', isInRange);
|
||
|
||
return isInRange;
|
||
};
|
||
|
||
|
||
function stockNumberIsFull(item) {
|
||
if (item.isStock && item.stockNumber < item.suitNum) {
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
/**
|
||
* 判断商品是否可售
|
||
* @param {Object} item
|
||
*/
|
||
function juageProductAvailable(item, i) {
|
||
if (!isProductAvailable(item.days, item.startTime, item.endTime)) {
|
||
uni.showToast({
|
||
title: '不在可售时间内'
|
||
});
|
||
return false;
|
||
}
|
||
if (item.isStock && item.stockNumber < item.suitNum && i == '+') {
|
||
uni.showToast({
|
||
title: '库存不足',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// 单规格
|
||
const singleclick = async (item, i) => {
|
||
console.log('单规格商品点击事件:', item, i);
|
||
if (!juageProductAvailable(item, i)) {
|
||
return false;
|
||
}
|
||
// 判断购物车是否有该选中商品
|
||
let res = null;
|
||
try {
|
||
res = matchedProducts.value.find((product, index) => {
|
||
return product.skuId == item.skuId && product.id == item.id;
|
||
});
|
||
} catch (error) {
|
||
//TODO handle the exception
|
||
}
|
||
|
||
// 保存这次点击的
|
||
specifications.productListitem = item;
|
||
|
||
// 是否起售 如果小于或者大于都是1
|
||
let suitNum = 1;
|
||
const cartNumberFloat = parseFloat(item.cartNumber);
|
||
if (!res && item.suitNum > cartNumberFloat) {
|
||
suitNum = item.suitNum;
|
||
} else if (item.suitNum >= cartNumberFloat && i === '-') {
|
||
suitNum = item.cartNumber;
|
||
}
|
||
const sendMsg = {
|
||
type: 'shopping',
|
||
suitNum: item.suitNum,
|
||
table_code: uni.cache.get('tableCode'),
|
||
shop_id: uni.cache.get('shopId'),
|
||
operate_type: (await calculateValue(item.cartNumber, i, suitNum)) == 'del' ? 'del' : res ? 'edit' :
|
||
'add',
|
||
product_id: item.id,
|
||
sku_id: item.skuId,
|
||
memberPrice: item.memberPrice,
|
||
number: await calculateValue(item.cartNumber, i, suitNum),
|
||
is_print: 1,
|
||
product_type: item.type,
|
||
is_time_discount: showLimitDiscount(item)
|
||
};
|
||
if (item.cartListId) {
|
||
sendMsg.id = item.cartListId;
|
||
}
|
||
websocketsendMessage(sendMsg);
|
||
};
|
||
|
||
const calculateValue = (cartNumber, i, step = 1) => {
|
||
if (i == '+') {
|
||
const result = parseFloat(cartNumber) + parseFloat(step);
|
||
return result.toFixed(2);
|
||
} else {
|
||
// 当减到0返回del
|
||
const result = parseFloat(cartNumber) - parseFloat(step);
|
||
return result == 0 ? 'del' : result.toFixed(2);
|
||
}
|
||
};
|
||
|
||
// WebSocket处理 // 初始化配置
|
||
const options = {
|
||
initMessage: {
|
||
type: 'shopping',
|
||
operate_type: 'init',
|
||
table_code: uni.cache.get('tableCode'),
|
||
shop_id: uni.cache.get('shopId'),
|
||
time_dis_info: null
|
||
}
|
||
};
|
||
const useSocket = useWebSocket();
|
||
//购物车显示
|
||
const showCart = ref(false);
|
||
|
||
// 提交订单显示
|
||
const confirmordershow = ref(false);
|
||
|
||
// 更新商品数量的方法
|
||
const updateProductQuantities = () => {
|
||
console.log('updateProductQuantities');
|
||
// 先将所有商品的 cartNumber 初始化为 0
|
||
shopProductList.hots.forEach((i) => {
|
||
i.cartNumber = 0;
|
||
});
|
||
// 遍历商品列表二维数组
|
||
shopProductList.productInfo.forEach((group) => {
|
||
group.productList.forEach((product) => {
|
||
product.cartNumber = 0;
|
||
});
|
||
});
|
||
|
||
// 再去更新数组的值
|
||
cartListFilter.value.forEach((cartItem) => {
|
||
shopProductList.productInfo.forEach((group) => {
|
||
group.productList.forEach((product) => {
|
||
if (product.id == cartItem.product_id && product.skuId == cartItem
|
||
.sku_id) {
|
||
product.cartNumber = cartItem.number || 0;
|
||
product.cartListId = cartItem.id;
|
||
}
|
||
});
|
||
});
|
||
});
|
||
// 遍历购物车数组
|
||
cartListFilter.value.forEach((cartItem) => {
|
||
// 遍历商品列表二维数组
|
||
shopProductList.hots.forEach((group) => {
|
||
// 商品 id 匹配
|
||
if (group.id == cartItem.product_id) {
|
||
// 更新商品的数量
|
||
group.cartListId = cartItem.id;
|
||
group.cartNumber = cartItem.number || 0;
|
||
}
|
||
});
|
||
});
|
||
};
|
||
|
||
//websocket产值
|
||
const websocketsendMessage = (data) => {
|
||
console.log('websocketsendMessage', data);
|
||
delete data.memberPrice;
|
||
uni.$u.debounce(() => {
|
||
useSocket.sendMessage(data);
|
||
}, 200);
|
||
};
|
||
|
||
// 用于记录已经处理过的消息的 msg_id
|
||
const processedMessageIds = new Set();
|
||
|
||
//设置商品初始选中
|
||
function setGoodsInitSel(cartsArr) {
|
||
console.log('setGoodsInitSel');
|
||
const arr = cartsArr && cartsArr.length ? cartsArr : cartStore.carts;
|
||
if (arr.length <= 0) {
|
||
return;
|
||
}
|
||
shopProductList.hots.map((v) => {
|
||
const item = arr.find((cart) => cart.product_id == v.id);
|
||
if (item) {
|
||
v.cartNumber = `${item.number}`;
|
||
}
|
||
});
|
||
shopProductList.productInfo.map((info) => {
|
||
info.productList.map((v) => {
|
||
const item = arr.find((cart) => cart.product_id == v.id);
|
||
if (item) {
|
||
v.cartNumber = `${item.number}`;
|
||
console.log(v.cartNumber);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
async function delGoods() {
|
||
await websocketsendMessage({
|
||
id: Message.id,
|
||
type: 'shopping',
|
||
table_code: uni.cache.get('tableCode'),
|
||
shop_id: uni.cache.get('shopId'),
|
||
operate_type: 'del',
|
||
is_print: 1
|
||
});
|
||
}
|
||
|
||
// 购物车初始化时进行判断商品是否可以使用限时折扣,然后更新
|
||
let socketTimer = null
|
||
|
||
// 返回商品对应sku数据
|
||
|
||
function cartInit(arr) {
|
||
|
||
const result = []
|
||
cartStore.carts = arr.map(v => {
|
||
const goods = cartStore.allGoodsArr.find(g => g.id == v.product_id)
|
||
const goodsSkuList = goods ? goods.skuList : []
|
||
const findSku = goodsSkuList.find(sku => sku.id == v.sku_id)
|
||
const memberPrice = findSku ? findSku.memberPrice : 0
|
||
const is_temporary=v.is_temporary||v.isTemporary
|
||
const is_time_discount = limitUtils.canUseLimitTimeDiscount({
|
||
...v,
|
||
memberPrice
|
||
}, cartStore.limitTimeDiscount, shopInfo,
|
||
shopUserInfo.value, 'product_id');
|
||
if (!goods&&!is_temporary) {
|
||
console.log('删除未匹配到的商品', {
|
||
id: v.id,
|
||
operate_type: "del",
|
||
table_code: uni.cache.get('tableCode'),
|
||
shop_id: uni.cache.get('shopId'),
|
||
type: "shopping",
|
||
})
|
||
useSocket.sendMessage({
|
||
id: v.id,
|
||
operate_type: "del",
|
||
table_code: uni.cache.get('tableCode'),
|
||
shop_id: uni.cache.get('shopId'),
|
||
type: "shopping",
|
||
});
|
||
return null
|
||
}
|
||
return {
|
||
...v,
|
||
is_time_discount: is_time_discount ? 1 : 0,
|
||
memberPrice
|
||
}
|
||
}).filter(v => v)
|
||
|
||
for (let cart of arr) {
|
||
const findItem = cartStore.carts.find(v => v.id == cart.id)
|
||
if (findItem && findItem.is_time_discount != cart.is_time_discount) {
|
||
result.push({
|
||
id: cart.id,
|
||
is_time_discount: findItem.is_time_discount
|
||
})
|
||
}
|
||
}
|
||
if (result.length > 0) {
|
||
useSocket.sendMessage({
|
||
table_code: uni.cache.get('tableCode'),
|
||
shop_id: uni.cache.get('shopId'),
|
||
type: "shopping",
|
||
operate_type: "bulk_edit",
|
||
data: {
|
||
cart: result
|
||
}
|
||
});
|
||
|
||
}
|
||
}
|
||
|
||
let socketInitFinished = false
|
||
// 收到的消息变化
|
||
async function onMessage(Message) {
|
||
if (Message) {
|
||
// 心跳返回 过滤
|
||
if (Message.type == 'ping_interval' || Message.msg_id == 'ping_interval') {
|
||
isLoading.value = false;
|
||
return false;
|
||
}
|
||
|
||
// 检查消息是否已经处理过
|
||
if (processedMessageIds.has(Message.msg_id)) {
|
||
return;
|
||
}
|
||
processedMessageIds.add(Message.msg_id);
|
||
|
||
// 初始化
|
||
if (Message.operate_type == 'init') {
|
||
// cartStore.limitTimeDiscount = Message.time_dis_info;
|
||
cartInit(Message.data)
|
||
|
||
uni.hideLoading();
|
||
isLoading.value = false;
|
||
|
||
if (!socketInitFinished) {
|
||
useSocket.chnageInitMessage(options.initMessage)
|
||
socketInitFinished = true
|
||
}
|
||
|
||
}
|
||
|
||
if (Message.operate_type == 'rottable_error') {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: Message.msg,
|
||
showCancel: true,
|
||
cancelText: '舍弃',
|
||
confirmText: '合并',
|
||
success(res) {
|
||
showTableInfoPeopleNumPopup.value = false;
|
||
if (res.confirm) {
|
||
startUseTable({
|
||
is_hb: 2
|
||
})
|
||
} else {
|
||
startUseTable({
|
||
is_hb: 2,
|
||
give_up: 1
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
// 转桌成功
|
||
if (Message.operate_type == 'rottable') {
|
||
|
||
console.log('转桌成功了');
|
||
console.log(Message);
|
||
|
||
// uni.showToast({
|
||
// title: '扫码成功,请下单',
|
||
// icon: 'none'
|
||
// });
|
||
|
||
orderType.value = 'scan';
|
||
uni.cache.set('tableCode', Message.data.new_table_code);
|
||
|
||
if (showTableInfoPeopleNumPopup.value == true) {
|
||
showTableInfoPeopleNumPopup.value = false;
|
||
}
|
||
|
||
const data = {
|
||
type: 'shopping',
|
||
operate_type: 'init',
|
||
table_code: uni.cache.get('tableCode'),
|
||
shop_id: uni.cache.get('shopId'),
|
||
time_dis_info: cartStore.limitTimeDiscount
|
||
};
|
||
console.log('cartStore.limitTimeDiscount', cartStore.limitTimeDiscount)
|
||
// useSocket.sendMessage({
|
||
// type: 'shopping',
|
||
// operate_type: 'time_discount_save',
|
||
// table_code: Message.data.new_table_code,
|
||
// shop_id: uni.cache.get('shopId'),
|
||
// operate_type: 'time_discount_save',
|
||
// data: cartStore.limitTimeDiscount
|
||
// });
|
||
useSocket.sendMessage(data);
|
||
}
|
||
|
||
// 清空购物车
|
||
if (Message.operate_type == 'cleanup') {
|
||
cartStore.carts = [];
|
||
setTimeout(() => {
|
||
Historicalorders();
|
||
}, 400);
|
||
showCart.value = false;
|
||
}
|
||
|
||
// 删除除购物车
|
||
if (Message.operate_type == 'del' && Message.status == 1) {
|
||
// 优化:使用可选链操作符避免报错
|
||
cartStore.carts = cartStore.carts.filter((item) => item.id !== Message.data?.id);
|
||
// cartStore.carts = cartStore.carts.filter(item => item.id != Message.data.id);
|
||
}
|
||
|
||
// 添加或者减少购物后返回
|
||
if (Message.operate_type == 'add' || Message.operate_type == 'edit') {
|
||
[Message.data].forEach((objA) => {
|
||
const index = cartStore.carts.findIndex((objB) => objB.id == objA.id);
|
||
if (index !== -1) {
|
||
cartStore.carts[index] = objA;
|
||
} else {
|
||
cartStore.carts.push(objA);
|
||
}
|
||
});
|
||
}
|
||
|
||
// 历史订单
|
||
if (Message.operate_type == 'clearOrder') {
|
||
Historicalorders();
|
||
}
|
||
|
||
// 购物车数据更新从新请求
|
||
if (Message.type == 'product' && Message.data_type == 'product_update' && Message.operate_type ==
|
||
'product_update') {
|
||
isDataLoaded.value = false;
|
||
productqueryProduct();
|
||
}
|
||
|
||
// 提示
|
||
if (Message.status == 0 && Message.type != 'no_suit_num' && Message.type != 'time_discount' && Message
|
||
.operate_type != 'rottable_error') {
|
||
uni.showToast({
|
||
title: Message.msg,
|
||
icon: 'none'
|
||
});
|
||
}
|
||
|
||
if (Message.type == 'no_suit_num') {
|
||
// console.log(specifications)
|
||
uni.showModal({
|
||
title: '提示',
|
||
showCancel: false,
|
||
content: '此商品库存不足起售数量!',
|
||
success: (data) => {
|
||
delGoods();
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
|
||
//除去p 每次返回都回执消息
|
||
await websocketsendMessage({
|
||
type: 'receipt',
|
||
msg_id: Message.msg_id
|
||
});
|
||
|
||
// 初始化商品数量
|
||
await updateProductQuantities();
|
||
}
|
||
}
|
||
|
||
// 更新购物车数据shopProductList.hots
|
||
const matchedProducts = computed(() => {
|
||
if (cartStore.carts.length > 0) {
|
||
let Specialstop = null;
|
||
|
||
try {
|
||
Specialstop = [
|
||
...[{
|
||
id: '',
|
||
name: '',
|
||
productList: shopProductList.hots
|
||
}],
|
||
...shopProductList.productInfo
|
||
];
|
||
} catch (error) {
|
||
Specialstop = shopProductList.productInfo;
|
||
//TODO handle the exception
|
||
}
|
||
return cartStore.carts
|
||
.flatMap((cartItem) => {
|
||
for (const group of Specialstop) {
|
||
for (const product of group.productList) {
|
||
if (product.id == cartItem.product_id) {
|
||
console.log(cartItem);
|
||
return {
|
||
...product,
|
||
cartListinfo: cartItem,
|
||
cartListId: cartItem.id, //购物车id
|
||
cartNumber: cartItem.number //增加一个数量算法
|
||
// cartNumberToAdd: cartItem.number //增加一个数量算法
|
||
};
|
||
}
|
||
}
|
||
}
|
||
if (cartItem.is_temporary === 1) {
|
||
return [{
|
||
...cartItem,
|
||
memberPrice: cartItem.discount_sale_amount,
|
||
salePrice: cartItem.discount_sale_amount,
|
||
cartListinfo: cartItem,
|
||
cartListId: cartItem.id, // 购物车id
|
||
cartNumber: cartItem.number // 增加一个数量算法
|
||
}];
|
||
}
|
||
// 如果没找到匹配的商品,返回 null 或者其他默认值,这里返回 null
|
||
return null;
|
||
})
|
||
.filter((item) => item !== null);
|
||
} else {
|
||
return [];
|
||
}
|
||
});
|
||
|
||
//删除某一个待支付订单
|
||
const clickcancelOrder = async (data) => {
|
||
if (data.i == 'all') {
|
||
await APIcancelOrder({
|
||
shopId: uni.cache.get('shopId'),
|
||
orderId: orderinfo.value.id
|
||
});
|
||
} else {
|
||
await APIrmPlaceOrder({
|
||
shopId: uni.cache.get('shopId'),
|
||
orderId: orderinfo.value.id,
|
||
placeNum: data.key
|
||
});
|
||
}
|
||
Historicalorders();
|
||
};
|
||
|
||
// 储存是否存在多次下单
|
||
const orderinfo = ref({});
|
||
const confirmorderref = ref(null);
|
||
|
||
// 结账
|
||
const orderdetail = async () => {
|
||
isAutoClose = false;
|
||
uni.navigateTo({
|
||
url: '/pages/order/confirm-order?tableCode=' + uni.cache.get('tableCode') + '&shopId=' + uni
|
||
.cache.get('shopId')
|
||
});
|
||
return;
|
||
try {
|
||
await Historicalorders();
|
||
} catch (error) {}
|
||
confirmordershow.value = true;
|
||
showCart.value = false;
|
||
};
|
||
|
||
// 历史订单
|
||
const Historicalorders = async (W) => {
|
||
if (W) {
|
||
showCart.value = !showCart.value;
|
||
} else {
|
||
let res = await APIhistoryOrder({
|
||
tableCode: uni.cache.get('tableCode')
|
||
});
|
||
if (res && typeof res === 'object') {
|
||
orderinfo.value = {
|
||
id: res.id,
|
||
detailMap: res.detailMap,
|
||
placeNum: res.placeNum
|
||
};
|
||
}
|
||
|
||
}
|
||
};
|
||
|
||
// 提取合并 orderinfo.detailMap 数组的逻辑
|
||
function combineOrderInfoDetailMap(orderinfo) {
|
||
if (!orderinfo) return [];
|
||
let combinedArray = [];
|
||
for (const key in orderinfo.detailMap) {
|
||
if (orderinfo.detailMap.hasOwnProperty(key)) {
|
||
let subArray = orderinfo.detailMap[key];
|
||
combinedArray = [...combinedArray, ...subArray];
|
||
}
|
||
}
|
||
return combinedArray;
|
||
}
|
||
|
||
// 计算购物车商品费用
|
||
const totalPrices = computed(() => {
|
||
// 购物车总数价格
|
||
let cart = 0;
|
||
if (matchedProducts.value.length > 0) {
|
||
// 购物车总数价格
|
||
cart = matchedProducts.value.reduce((total, item) => {
|
||
if (item.type == 'sku') {
|
||
item.skuList.forEach((i, t) => {
|
||
if (item.cartListinfo.sku_id == i.id) {
|
||
item.memberPrice = i.memberPrice;
|
||
item.salePrice = i.salePrice;
|
||
}
|
||
});
|
||
}
|
||
if (cartStore.limitTimeDiscount && cartStore.limitTimeDiscount.id && item.cartListinfo
|
||
.is_time_discount ==
|
||
1) {
|
||
//限时折扣
|
||
const price = limitUtils.returnPrice({
|
||
goods: item,
|
||
shopInfo,
|
||
limitTimeDiscountRes: cartStore.limitTimeDiscount,
|
||
shopUserInfo: shopUserInfo.value,
|
||
idKey: 'id'
|
||
});
|
||
return total + parseFloat(price) * parseFloat(item.cartNumber);
|
||
}
|
||
// 是否启用会员价 0否1是
|
||
if (shopUserInfo.value.isVip == 1 && shopUserInfo.value.isMemberPrice == 1) {
|
||
// memberPrice会员价
|
||
return total + parseFloat(item.memberPrice || item.salePrice) * parseFloat(item
|
||
.cartNumber);
|
||
} else {
|
||
// salePrice销售价
|
||
return total + parseFloat(item.salePrice || 0) * parseFloat(item.cartNumber);
|
||
}
|
||
}, 0);
|
||
}
|
||
cart = parseFloat(cart);
|
||
// 向上取整并保留两位小数
|
||
return parseFloat(cart.toFixed(2));
|
||
});
|
||
|
||
//全部优惠券金额
|
||
const allDiscountMoney = computed(() => {
|
||
let discountMoney = 0;
|
||
// 新客立减
|
||
if (newUserDiscount.value && newUserDiscount.value.amount) {
|
||
discountMoney += newUserDiscount.value.amount;
|
||
}
|
||
// 满减活动
|
||
if (fullAmountActivty.value && fullAmountActivty.value.discountAmount) {
|
||
discountMoney += fullAmountActivty.value.discountAmount;
|
||
}
|
||
return discountMoney.toFixed(2);
|
||
});
|
||
|
||
// 计算实际金额(购物车商品费用-新客立减-满减活动)
|
||
const actualPrice = computed(() => {
|
||
let price = BigNumber(totalPrices.value * 1)
|
||
.minus(allDiscountMoney.value * 1)
|
||
.toFixed(2);
|
||
return price <= 0 ? 0 : price;
|
||
});
|
||
|
||
// 计算购物车商品总数量
|
||
const cartLists_count = computed(() => {
|
||
const combinedOrderInfo = combineOrderInfoDetailMap(orderinfo.value);
|
||
const orderInfoCount = combinedOrderInfo.reduce((sum, item) => {
|
||
return sum + parseFloat(item.num);
|
||
}, 0);
|
||
|
||
const matchedProductsCount = matchedProducts.value.reduce((sum, item) => {
|
||
const num = typeof item.cartNumber === 'string' ? parseFloat(item.cartNumber) : item
|
||
.cartNumber;
|
||
return sum + num;
|
||
}, 0);
|
||
|
||
const totalCount = matchedProductsCount;
|
||
return parseFloat(totalCount.toFixed(2));
|
||
});
|
||
|
||
// 定义 ifcartNumber 计算属性方法 展示数量
|
||
function ifcartNumber(item) {
|
||
// 如果 item 为空或者 cartNumber 不是字符串类型,返回 0
|
||
if (!item || item.cartNumber * 1 == 0) {
|
||
return '';
|
||
}
|
||
let numValue = parseFloat(item.cartNumber);
|
||
if (isNaN(numValue)) {
|
||
// 如果转换结果是 NaN,说明 cartNumber 不是有效的数字字符串,返回 0
|
||
return '';
|
||
}
|
||
// type string 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券
|
||
if (item.type === 'weight') {
|
||
// 如果类型是称重重量,将值保留两位小数
|
||
return parseFloat(numValue.toFixed(2));
|
||
} else {
|
||
// 如果类型是整数,将值转换为整数
|
||
return Math.round(numValue);
|
||
}
|
||
// 如果类型不匹配,返回原始值
|
||
return item.cartNumber;
|
||
}
|
||
|
||
// 计算处理后的购物车列表 // 用于筛选后的购物车数组
|
||
const cartListFilter = computed(() => {
|
||
// 使用 reduce 方法对 cartList 进行处理
|
||
const grouped = cartStore.carts.reduce((acc, item) => {
|
||
const productId = item.product_id;
|
||
const num = parseFloat(item.number);
|
||
|
||
if (!acc[productId]) {
|
||
// 如果 acc 中还没有该 product_id 的记录,创建一个新对象
|
||
acc[productId] = {
|
||
...item,
|
||
number: num
|
||
};
|
||
} else {
|
||
// 如果已经有该 product_id 的记录,将当前对象的 number 值累加到已有记录的 number 属性上
|
||
acc[productId].number += num;
|
||
}
|
||
return acc;
|
||
}, {});
|
||
// 将累加结果保留两位小数,并将对象转换为数组
|
||
return Object.values(grouped).map((item) => ({
|
||
...item,
|
||
number: item.number.toFixed(2)
|
||
}));
|
||
});
|
||
|
||
const endTimeref = reactive({
|
||
startTime: '',
|
||
endTime: ''
|
||
});
|
||
|
||
// 获取当前时间
|
||
const getCurrentTime = () => {
|
||
const now = new Date();
|
||
const hours = now.getHours().toString().padStart(2, '0');
|
||
const minutes = now.getMinutes().toString().padStart(2, '0');
|
||
return `${hours}:${minutes}`;
|
||
};
|
||
|
||
// 计算是否在营业时间内
|
||
const isBusinessTime = computed(() => {
|
||
if (!shopInfo.businessTime) {
|
||
return true;
|
||
}
|
||
const currentTime = getCurrentTime();
|
||
const [startTime, endTime] = shopInfo.businessTime.split('-');
|
||
endTimeref.startTime = startTime;
|
||
endTimeref.endTime = endTime;
|
||
// 如果开始时间大于结束时间,说明是跨天的营业时间
|
||
if (startTime > endTime) {
|
||
return currentTime >= startTime || currentTime <= endTime;
|
||
}
|
||
return currentTime >= startTime && currentTime <= endTime;
|
||
});
|
||
const allGoodsArr = ref([])
|
||
// 列表请求
|
||
const productqueryProduct = async () => {
|
||
cartStore.goodsIsloading = false;
|
||
allGoodsArr.value=[]
|
||
try {
|
||
shopProductList.hots = await productminiApphotsquery();
|
||
shopProductList.productInfo = await APIgroupquery();
|
||
} catch (error) {
|
||
uni.showToast({
|
||
title: '网络不稳定,请重新扫码进入',
|
||
icon: 'none'
|
||
});
|
||
setTimeout(() => {
|
||
uni.pro.switchTab('index/index');
|
||
}, 1000);
|
||
return; // 出错直接返回,避免后续逻辑
|
||
}
|
||
|
||
if (shopProductList.productInfo.length > 0 || shopProductList.hots.length > 0) {
|
||
// 第一步:处理productInfo(替换forEach为for...of,支持await)
|
||
for (const group of shopProductList.productInfo) {
|
||
for (const product of group.productList) {
|
||
product.cartNumber = 0;
|
||
// 等待异步函数执行完成后,再push
|
||
product.isSaleTimeshow = await isProductAvailable(
|
||
product.days,
|
||
product.startTime,
|
||
product.endTime
|
||
);
|
||
allGoodsArr.value.push(product);
|
||
cartStore.setGoodsMap(product.id, product);
|
||
}
|
||
}
|
||
|
||
// 第二步:处理hots(同理替换forEach为for...of)
|
||
for (const i of shopProductList.hots) {
|
||
i.cartNumber = 0;
|
||
i.isSaleTimeshow = await isProductAvailable(i.days, i.startTime, i.endTime);
|
||
allGoodsArr.value.push(i);
|
||
cartStore.setGoodsMap(i.id, i);
|
||
}
|
||
|
||
// 此时所有异步操作完成,allGoodsArr已有数据
|
||
// console.log('allGoodsArr', allGoodsArr);
|
||
// console.log('shopProductList', shopProductList);
|
||
console.log('cartStore.carts', cartStore.carts)
|
||
cartStore.allGoodsArr=allGoodsArr.value
|
||
if (cartStore.carts.length > 0) {
|
||
cartInit(cartStore.carts);
|
||
}
|
||
|
||
cartStore.goodsIsloading = true;
|
||
scrollTopSize.value = 0;
|
||
topArr.value = [];
|
||
isDataLoaded.value = true;
|
||
Historicalorders();
|
||
updateProductQuantities();
|
||
} else {
|
||
uni.showToast({
|
||
title: '暂无列表数据,请重新扫码',
|
||
icon: 'none'
|
||
});
|
||
isDataLoaded.value = false;
|
||
setTimeout(() => {
|
||
uni.pro.switchTab('index/index');
|
||
}, 1000);
|
||
return false;
|
||
}
|
||
};
|
||
|
||
provide('cartStore', cartStore);
|
||
provide('shopUserInfo', shopUserInfo);
|
||
provide('shopInfo', shopInfo);
|
||
|
||
const orderType = ref('scan');
|
||
|
||
// 扫码下单
|
||
|
||
// 台桌信息
|
||
const showTableInfoPeopleNumPopup = ref(false);
|
||
const tableInfo = ref('');
|
||
const tableShopInfo = ref(uni.cache.get('shopInfo'));
|
||
|
||
// 选择的人数
|
||
const tableInfoPeopleActive = ref(-1);
|
||
const tableInfoPeopleNum = ref('');
|
||
|
||
// 选择人数
|
||
function tableInfoPeopleNumHandle(num, index) {
|
||
tableInfoPeopleActive.value = index;
|
||
tableInfoPeopleNum.value = num;
|
||
}
|
||
|
||
// 人数输入框
|
||
function tableInfoPeopleNumInput(e) {
|
||
tableInfoPeopleActive.value = -1;
|
||
setTimeout(() => {
|
||
tableInfoPeopleNum.value = filterNumberInput(e, 1);
|
||
}, 50);
|
||
}
|
||
|
||
// 取消选择人数
|
||
function closeTableInfoPeopleNum() {
|
||
showTableInfoPeopleNumPopup.value = false;
|
||
tableInfoPeopleActive.value = -1;
|
||
tableInfoPeopleNum.value = '';
|
||
}
|
||
|
||
// 确认选择人数
|
||
function tableInfoPeopleNumConfirm() {
|
||
if (tableInfoPeopleNum.value > 0) {
|
||
uni.cache.set('dinersNum', tableInfoPeopleNum.value);
|
||
startUseTable();
|
||
} else {
|
||
uni.showToast({
|
||
title: '请选择就餐人数',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
}
|
||
|
||
// 开始换桌
|
||
function startUseTable(par) {
|
||
tableShopInfo.value = uni.cache.get('shopInfo');
|
||
const oldTableCode = uni.cache.get('tableCode');
|
||
const cartIds = cartStore.carts.map((item) => item.id);
|
||
|
||
const data = {
|
||
is_hb: 1,
|
||
...par,
|
||
type: 'shopping',
|
||
operate_type: 'rottable',
|
||
account: tableShopInfo.value.phone,
|
||
table_code: oldTableCode,
|
||
new_table_code: uni.cache.get('shopTable').tableCode,
|
||
cart_id: cartIds,
|
||
shop_id: tableShopInfo.value.id,
|
||
};
|
||
|
||
websocketsendMessage(data);
|
||
}
|
||
|
||
const juli = computed(() => {
|
||
const juli = getDistance(userStore.location.latitude, userStore.location.longitude, shopInfo.lat,
|
||
shopInfo.lng);
|
||
return juli.toFixed(2)
|
||
})
|
||
|
||
|
||
//计算距离判断是否可以点餐
|
||
async function computedDistance(shopInfo) {
|
||
return new Promise((resolve, reject) => {
|
||
console.log('店铺经纬度', shopInfo.lat, shopInfo.lng);
|
||
console.log('用户经纬度', userStore.location.latitude, userStore.location.longitude);
|
||
|
||
const juli = getDistance(userStore.location.latitude, userStore.location.longitude, shopInfo.lat,
|
||
shopInfo.lng);
|
||
const orderFenceDistance = ((shopInfo.orderFenceDistance || 2000) / 2000).toFixed(2);
|
||
|
||
console.log('距离', juli);
|
||
|
||
if (shopInfo.isOrderFence && juli > orderFenceDistance) {
|
||
uni.showModal({
|
||
title: '提示',
|
||
confirmText: '重新定位',
|
||
content: '抱歉,您当前距离店铺过远,为保障您的用餐体验,请您到店后或在门店附近再下单。若您已在店铺附近,可尝试重新定位',
|
||
success: async (res) => {
|
||
if (res.confirm) {
|
||
console.log('用户点击了确认');
|
||
await userStore.getLocation();
|
||
// computedDistance();
|
||
uni.showToast({
|
||
title: '定位成功,请重新扫码',
|
||
icon: 'none'
|
||
});
|
||
} else if (res.cancel) {
|
||
console.log('用户点击了取消');
|
||
}
|
||
}
|
||
});
|
||
reject();
|
||
return;
|
||
}
|
||
resolve(juli);
|
||
});
|
||
}
|
||
|
||
// 预点单扫码下单
|
||
function beforehandHandle() {
|
||
isAutoClose = false
|
||
uni.scanCode({
|
||
success: async (res) => {
|
||
try {
|
||
|
||
|
||
console.log('options.initMessage', options.initMessage)
|
||
const newTableCode = userStore.getQueryString(res.result, 'code');
|
||
|
||
const shopInfoRes = await APIproductqueryShop({
|
||
tableCode: newTableCode
|
||
});
|
||
|
||
console.log('shopInfoRes===', shopInfoRes);
|
||
|
||
await computedDistance(shopInfoRes.shopInfo);
|
||
if (shopInfoRes.shopInfo.id !== shopInfo.id) {
|
||
uni.showModal({
|
||
title: '注意',
|
||
content: '扫码店铺与当前店铺不一致,请重新加载页面',
|
||
showCancel: false,
|
||
success: async (res) => {
|
||
uni.cache.set('tableCode', newTableCode);
|
||
await userStore.actionsproductqueryShop(newTableCode);
|
||
await userStore.actionsproductqueryProduct();
|
||
useSocket.closeSocket();
|
||
userStore.jumpToOrderPage();
|
||
}
|
||
});
|
||
} else {
|
||
await userStore.actionsproductqueryShop(newTableCode);
|
||
await userStore.actionsproductqueryProduct();
|
||
const res = await APIhistoryOrder({
|
||
tableCode: newTableCode
|
||
});
|
||
|
||
if (res && res.id) {
|
||
return uni.showModal({
|
||
title: '提示',
|
||
content: '目标台桌使用中无法转桌',
|
||
showCancel: false
|
||
})
|
||
}
|
||
if (shopInfoRes.shopInfo.isTableFee === 1) {
|
||
// 免桌位费,直接换桌
|
||
startUseTable();
|
||
} else {
|
||
// 不免桌位费,显示选择人数
|
||
tableInfo.value = uni.cache.get('shopTable');
|
||
showTableInfoPeopleNumPopup.value = true;
|
||
}
|
||
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
onLoad(async (e) => {
|
||
if (e.type) {
|
||
orderType.value = e.type;
|
||
}
|
||
//获取用户信息
|
||
const userInfo = await APIshopUserInfo({
|
||
shopId: uni.cache.get('shopId')
|
||
})
|
||
//获取店铺信息
|
||
const shopInfoRes = await APIusershopInfodetail({
|
||
shopId: uni.cache.get('shopId')
|
||
});
|
||
if (shopInfoRes && shopInfoRes.shopInfo) {
|
||
Object.assign(shopInfo, shopInfoRes.shopInfo);
|
||
uni.cache.set('shopInfo', shopInfoRes.shopInfo)
|
||
}
|
||
|
||
|
||
if (userInfo && typeof userInfo === 'object') {
|
||
shopUserInfo.value = userInfo
|
||
uni.cache.set('shopUserInfo', userInfo)
|
||
}
|
||
await productqueryProduct();
|
||
|
||
const extraInitPar = {}
|
||
if (e.one_more_order && e.order_id) {
|
||
extraInitPar.one_more_order = 1
|
||
extraInitPar.order_id = e.order_id
|
||
extraInitPar.user_id = uni.cache.get('userInfo').id || ''
|
||
}
|
||
|
||
const time_dis_info = await getLimitDiscount()
|
||
options.initMessage.time_dis_info = time_dis_info
|
||
useSocket.connect({
|
||
...options.initMessage,
|
||
...extraInitPar,
|
||
}, onMessage);
|
||
|
||
cartStore.setOldOrder({
|
||
detailMap: {},
|
||
originAmount: 0
|
||
});
|
||
|
||
|
||
//新客立减
|
||
getNewUserDiscount();
|
||
// 满减活动
|
||
getDiscountActivity();
|
||
|
||
let res = await APIhistoryOrder({
|
||
tableCode: uni.cache.get('tableCode')
|
||
});
|
||
oldOrder.value = res;
|
||
if (res && res.id && shopInfo.registerType == 'after' && !e.noJump) {
|
||
toHistory();
|
||
return;
|
||
}
|
||
setTimeout(() => {
|
||
// 启动网络监听
|
||
useSocket.initNetworkListener();
|
||
getElementTop();
|
||
}, 500);
|
||
});
|
||
|
||
const nowTime = ref(getEndTimeInSeconds(dayjs().format('HH:mm')));
|
||
let timer = setInterval(() => {
|
||
nowTime.value = getEndTimeInSeconds(dayjs().format('HH:mm'));
|
||
}, 1000);
|
||
|
||
function getEndTimeInSeconds(endTime) {
|
||
const [hour, minute] = endTime.split(':').map(Number);
|
||
return hour * 60 * 60 + minute * 60;
|
||
}
|
||
// 将秒再转为hh::mm
|
||
function secondsToHHMM(seconds) {
|
||
const hours = Math.floor(seconds / 60 / 60);
|
||
const minutes = Math.floor(seconds / 60) % 60;
|
||
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
|
||
}
|
||
|
||
const limitDiscountCountdown = computed(() => {
|
||
if (!cartStore.limitTimeDiscount && !cartStore.limitTimeDiscount.id) {
|
||
return '';
|
||
}
|
||
if (cartStore.limitTimeDiscount.useTimeType != 'custom') {
|
||
return '';
|
||
}
|
||
//根据当前时间和限时折扣的结束时间计算倒计时,结束时间是hh:mm,将hh:mm转换为时间多少秒,然后再减去当前时间,就得到了倒计时
|
||
const endTime = getEndTimeInSeconds(cartStore.limitTimeDiscount.useEndTime);
|
||
const countdown = endTime - nowTime.value;
|
||
if (countdown <= 0) {
|
||
return '';
|
||
}
|
||
return secondsToHHMM(countdown);
|
||
});
|
||
|
||
function showLimitDiscount(item) {
|
||
if (!cartStore.limitTimeDiscount || !cartStore.limitTimeDiscount.id) {
|
||
return 0;
|
||
}
|
||
return limitUtils.canUseLimitTimeDiscount(item, cartStore.limitTimeDiscount, shopInfo, shopUserInfo.value, 'id') ?
|
||
1 : 0;
|
||
}
|
||
|
||
function returnLimitPrice(item) {
|
||
return limitUtils.returnPrice({
|
||
goods: item,
|
||
limitTimeDiscountRes: cartStore.limitTimeDiscount,
|
||
shopInfo: shopInfo,
|
||
shopUserInfo: shopUserInfo.value,
|
||
idKey: 'id'
|
||
});
|
||
}
|
||
|
||
function watchEmit() {
|
||
uni.$off('updateProductIndex')
|
||
uni.$on('updateProductIndex', function(data) {
|
||
getNewUserDiscount()
|
||
})
|
||
}
|
||
|
||
onShow(async () => {
|
||
isAutoClose = true;
|
||
// 监听页面显示和隐藏
|
||
watchEmit()
|
||
useSocket.setOnMessage(onMessage);
|
||
useSocket.onShowconnect();
|
||
let res = await APIhistoryOrder({
|
||
tableCode: uni.cache.get('tableCode')
|
||
});
|
||
if (res) {
|
||
orderinfo.value = {
|
||
id: res.id,
|
||
detailMap: res.detailMap,
|
||
placeNum: res.placeNum
|
||
};
|
||
} else {
|
||
orderinfo.value = {
|
||
id: ''
|
||
};
|
||
}
|
||
});
|
||
|
||
//是否自动关闭socket
|
||
let isAutoClose = true;
|
||
|
||
function closeSocket() {
|
||
if (isAutoClose) {
|
||
useSocket.closeSocket();
|
||
}
|
||
useSocket.setOnMessage(() => {});
|
||
}
|
||
onHide(() => {
|
||
closeSocket();
|
||
});
|
||
onUnload(() => {
|
||
closeSocket();
|
||
});
|
||
|
||
// 获取新客立减
|
||
|
||
const newUserDiscount = ref(null);
|
||
async function getNewUserDiscount() {
|
||
let res = await consumeDiscount({
|
||
shopId: uni.cache.get('shopId')
|
||
});
|
||
if (res && typeof res == 'object') {
|
||
newUserDiscount.value = res;
|
||
cartStore.consumeDiscount = res
|
||
cartStore.newUserDiscount = res.amount
|
||
} else {
|
||
newUserDiscount.value = null;
|
||
cartStore.consumeDiscount = {}
|
||
cartStore.newUserDiscount = 0
|
||
}
|
||
}
|
||
|
||
const fullAmountActivity = ref(null);
|
||
//获取满减活动
|
||
async function getDiscountActivity() {
|
||
const res = await discountActivityApi.config({
|
||
shopId: uni.cache.get('shopId')
|
||
});
|
||
if (res && typeof res == 'object') {
|
||
res.thresholds = (res.thresholds || []).sort((a, b) => {
|
||
return a.fullAmount - b.fullAmount
|
||
})
|
||
fullAmountActivity.value = res;
|
||
}
|
||
}
|
||
|
||
//返回当前满足的满减的活动
|
||
const fullAmountActivty = computed(() => {
|
||
if (!fullAmountActivity.value) {
|
||
return null;
|
||
}
|
||
//下一个满足满减的
|
||
let fullAmount = null;
|
||
for (let i in fullAmountActivity.value.thresholds) {
|
||
const item = fullAmountActivity.value.thresholds[i]
|
||
if (totalPrices.value * 1 >= item.fullAmount) {
|
||
fullAmount = item;
|
||
}
|
||
}
|
||
|
||
return fullAmount;
|
||
});
|
||
|
||
//返回下一个满减活动
|
||
const nextFullAmountActivty = computed(() => {
|
||
if (!fullAmountActivity.value) {
|
||
return null;
|
||
}
|
||
//下一个满足满减的
|
||
let nextFullAmount = null;
|
||
for (let item of fullAmountActivity.value.thresholds) {
|
||
if (totalPrices.value * 1 < item.fullAmount) {
|
||
nextFullAmount = item;
|
||
break;
|
||
}
|
||
}
|
||
return nextFullAmount;
|
||
});
|
||
const nextFullAmountActivtyAgignDiscount = computed(() => {
|
||
if (nextFullAmountActivty.value && fullAmountActivty.value) {
|
||
return nextFullAmountActivty.value.discountAmount - fullAmountActivty.value.discountAmount
|
||
}
|
||
if (nextFullAmountActivty.value && !fullAmountActivty.value) {
|
||
return nextFullAmountActivty.value.discountAmount
|
||
}
|
||
return 0
|
||
})
|
||
const oldOrder = ref(null);
|
||
|
||
|
||
// 限时折扣
|
||
async function getLimitDiscount() {
|
||
const limitRes = await limitTimeDiscountapi.getConfig({
|
||
shopId: uni.cache.get('shopId')
|
||
});
|
||
if (limitRes && typeof limitRes == 'object') {
|
||
cartStore.limitTimeDiscount = limitRes;
|
||
} else {
|
||
cartStore.limitTimeDiscount = null;
|
||
}
|
||
return cartStore.limitTimeDiscount
|
||
}
|
||
onMounted(async () => {
|
||
|
||
});
|
||
|
||
//跳转历史订单
|
||
function toHistory() {
|
||
isAutoClose = false;
|
||
const tableCode = uni.cache.get('tableCode');
|
||
const shopId = uni.cache.get('shopId');
|
||
let url = `/pages/order/confirm-order?tableCode=${tableCode}&shopId=${shopId}`;
|
||
const res = oldOrder.value;
|
||
console.log('toHistory', res);
|
||
// if (res && res.id && shopInfo.registerType == 'after') {
|
||
// url+='&orderId='+res.id
|
||
// }
|
||
uni.navigateTo({
|
||
url
|
||
});
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.grayscale {
|
||
filter: grayscale(100%);
|
||
pointer-events: none;
|
||
}
|
||
|
||
.top--panel {
|
||
// padding: 0 20rpx;
|
||
background-color: #fff;
|
||
|
||
.panelimgbackground {
|
||
width: 100%;
|
||
height: 272rpx;
|
||
}
|
||
|
||
.panelone {
|
||
padding: 20rpx 20rpx 0 20rpx;
|
||
font-weight: 500;
|
||
font-size: 32rpx;
|
||
color: #333333;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.paneltow {
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
|
||
.panelthere {
|
||
margin-top: 32rpx;
|
||
margin-bottom: 50rpx;
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
padding: 0 20rpx;
|
||
|
||
.paneltheretext {
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
|
||
.flex-start {
|
||
view {
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
}
|
||
|
||
.panelfour {
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: bold;
|
||
font-size: 32rpx;
|
||
color: #333333;
|
||
padding: 0 20rpx;
|
||
}
|
||
|
||
.panelfive {
|
||
width: 100%;
|
||
padding: 0 20rpx;
|
||
|
||
.panelfive_list {
|
||
display: flex;
|
||
}
|
||
|
||
.panelfiveitem {
|
||
margin-top: 16rpx;
|
||
width: 340rpx;
|
||
margin-right: 30rpx;
|
||
position: relative;
|
||
flex-shrink: 0;
|
||
|
||
.panelfiveitemimage {
|
||
border-radius: 20rpx 20rpx 0rpx 0rpx;
|
||
width: 100%;
|
||
height: 204rpx;
|
||
}
|
||
|
||
.vifgoodsImg {
|
||
width: 100%;
|
||
height: 204rpx;
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
z-index: 20;
|
||
background-color: rgb(0, 0, 0, 0.5);
|
||
|
||
image {
|
||
padding: 30rpx;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
|
||
.panelfiveitemone {
|
||
font-weight: 500;
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
overflow: hidden; //超出的文本隐藏
|
||
text-overflow: ellipsis; //溢出用省略号显示
|
||
white-space: nowrap; //溢出不换行
|
||
|
||
}
|
||
|
||
.top-tag {
|
||
color: #999;
|
||
background-color: #F8F8F8;
|
||
padding: 6rpx 20rpx;
|
||
font-size: 10px;
|
||
white-space: nowrap;
|
||
|
||
}
|
||
|
||
.panelfiveitemtow {
|
||
margin-top: 16rpx;
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #ff534b;
|
||
}
|
||
|
||
.panelfiveitemthere {
|
||
margin-top: 12rpx;
|
||
// text:nth-child(1) {
|
||
// margin-left: 0;
|
||
// }
|
||
|
||
text {
|
||
padding: 4rpx 24rpx;
|
||
background: #f6f6f6;
|
||
border-radius: 8rpx 8rpx 8rpx 8rpx;
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: 400;
|
||
font-size: 20rpx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
|
||
.panelfiveitemfour {
|
||
margin-top: 12rpx;
|
||
width: 100%;
|
||
height: 36rpx;
|
||
line-height: 36rpx;
|
||
overflow: hidden; //超出的文本隐藏
|
||
text-overflow: ellipsis; //溢出用省略号显示
|
||
white-space: nowrap; //溢出不换行
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
|
||
.panelfiveitemfive {
|
||
margin-top: 8rpx;
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
|
||
.panelfiveitemsex {
|
||
.panelfiveitemsex_oen {
|
||
display: flex;
|
||
align-items: baseline;
|
||
|
||
.tips {
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #333333;
|
||
}
|
||
|
||
.price {
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: bold;
|
||
font-size: 36rpx;
|
||
color: #333333;
|
||
}
|
||
|
||
.originalprice {
|
||
margin-left: 10rpx;
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: 400;
|
||
font-size: 20rpx;
|
||
text-decoration: line-through;
|
||
}
|
||
|
||
.unit {
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: 400;
|
||
font-size: 36rpx;
|
||
color: #333333;
|
||
}
|
||
}
|
||
}
|
||
|
||
.panelfiveitemNum {
|
||
// position: absolute;
|
||
// bottom: 82rpx;
|
||
// right: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
|
||
.sku-wrap {
|
||
padding: 10rpx 20rpx;
|
||
background: #e3ad7f;
|
||
border-radius: 32rpx;
|
||
position: relative;
|
||
align-items: center;
|
||
white-space: nowrap;
|
||
|
||
.t {
|
||
font-size: 28rpx;
|
||
color: #fff;
|
||
}
|
||
|
||
.dot {
|
||
position: absolute;
|
||
top: -15rpx;
|
||
right: -10rpx;
|
||
background-color: #ff4b33;
|
||
color: #fff;
|
||
border-radius: 58rpx;
|
||
padding: 5rpx 14rpx;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 20rpx;
|
||
}
|
||
}
|
||
|
||
.Controls {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.num {
|
||
margin: 8rpx 8rpx 0 8rpx;
|
||
}
|
||
|
||
.btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
position: relative;
|
||
|
||
.btnClick {
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
position: absolute;
|
||
// bottom: 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.scroll-panel {
|
||
position: relative;
|
||
|
||
.list-box {
|
||
display: flex;
|
||
flex-direction: row;
|
||
flex-wrap: nowrap;
|
||
justify-content: flex-start;
|
||
align-items: flex-start;
|
||
align-content: flex-start;
|
||
font-size: 28rpx;
|
||
position: relative;
|
||
|
||
.left {
|
||
// width: 200rpx;
|
||
width: 156rpx;
|
||
background-color: #f6f6f6;
|
||
line-height: normal;
|
||
box-sizing: border-box;
|
||
font-size: 32rpx;
|
||
position: sticky;
|
||
top: 0;
|
||
|
||
// padding-bottom: 200rpx;
|
||
.item {
|
||
padding: 30rpx 30rpx;
|
||
// height: 92rpx;
|
||
// line-height: 92rpx;
|
||
position: relative;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #333333;
|
||
display: flex;
|
||
align-items: center;
|
||
// overflow: hidden;
|
||
// text-overflow: ellipsis;
|
||
// white-space: nowrap;
|
||
|
||
&+.item {
|
||
margin-top: 1px;
|
||
|
||
&::after {
|
||
// content: '';
|
||
// display: block;
|
||
// height: 0;
|
||
// border-top: #d6d6d6 solid 1px;
|
||
// width: 620upx;
|
||
// position: absolute;
|
||
// top: -1px;
|
||
// right: 0;
|
||
// transform: scaleY(0.5);
|
||
/* 1px像素 */
|
||
}
|
||
}
|
||
|
||
&.active {
|
||
color: #333;
|
||
background-color: #fff;
|
||
position: relative;
|
||
|
||
&::before {
|
||
content: '';
|
||
display: block;
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
border-left: #7e5c23 solid 4px;
|
||
height: 100%;
|
||
width: 0;
|
||
}
|
||
|
||
&::after {
|
||
content: '';
|
||
display: block;
|
||
position: absolute;
|
||
top: 0;
|
||
left: -15rpx;
|
||
bottom: 0;
|
||
margin: auto;
|
||
height: 30rpx;
|
||
width: 30rpx;
|
||
border-radius: 50%;
|
||
background-color: #7e5c23;
|
||
}
|
||
}
|
||
}
|
||
|
||
.items {
|
||
height: 90px;
|
||
position: relative;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #333333;
|
||
}
|
||
|
||
.fill-last {
|
||
height: 0;
|
||
width: 100%;
|
||
background: none;
|
||
}
|
||
}
|
||
|
||
.main {
|
||
background-color: #fff;
|
||
padding-left: 20rpx;
|
||
width: 0;
|
||
flex-grow: 1;
|
||
box-sizing: border-box;
|
||
position: relative;
|
||
|
||
.title {
|
||
line-height: normal;
|
||
padding: 30rpx 0;
|
||
font-size: 24rpx;
|
||
font-weight: bold;
|
||
color: #666;
|
||
background-color: #fff;
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 19;
|
||
}
|
||
|
||
.item {
|
||
padding-bottom: 16rpx;
|
||
border-bottom: #eee solid 1px;
|
||
}
|
||
|
||
.goods {
|
||
display: flex;
|
||
flex-direction: row;
|
||
flex-wrap: nowrap;
|
||
justify-content: flex-start;
|
||
align-content: center;
|
||
position: relative;
|
||
|
||
&+.goods {
|
||
margin-top: 16rpx;
|
||
}
|
||
|
||
&>image {
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
margin-right: 18rpx;
|
||
}
|
||
|
||
.goodsImg {
|
||
position: relative;
|
||
width: 200rpx;
|
||
height: 200rpx;
|
||
border-radius: 18rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.vifgoodsImg {
|
||
width: 200rpx;
|
||
height: 100%;
|
||
position: absolute;
|
||
border-radius: 18rpx;
|
||
top: 0;
|
||
left: 0;
|
||
z-index: 9;
|
||
background-color: rgb(0, 0, 0, 0.5);
|
||
|
||
image {
|
||
padding: 30rpx;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
|
||
.topSort {
|
||
width: 92rpx;
|
||
height: 38rpx;
|
||
text-align: center;
|
||
line-height: 38rpx;
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #ffffff;
|
||
border-radius: 20rpx 0rpx 20rpx 0rpx;
|
||
z-index: 10;
|
||
}
|
||
|
||
.topSort.c1 {
|
||
background: #fc5c2e;
|
||
}
|
||
|
||
.topSort.c2 {
|
||
background: #ef994e;
|
||
}
|
||
|
||
.topSort.c3 {
|
||
background: #f4b951;
|
||
}
|
||
|
||
.goods_right {
|
||
width: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-around;
|
||
position: relative;
|
||
padding-top: 5rpx;
|
||
padding-right: 20rpx;
|
||
padding-left: 18rpx;
|
||
box-sizing: border-box;
|
||
|
||
.name {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
font-weight: bold;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.describe,
|
||
.monthlySale,
|
||
.lookBack {
|
||
font-weight: 400;
|
||
font-size: 20rpx;
|
||
color: #999999;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.describe,
|
||
.name {
|
||
width: 270rpx;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.lookBack {
|
||
color: #ff534b;
|
||
}
|
||
|
||
.money {
|
||
font-weight: bold;
|
||
font-size: 20rpx;
|
||
color: #333;
|
||
display: flex;
|
||
align-items: baseline;
|
||
white-space: nowrap;
|
||
|
||
.money_num {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
|
||
.suit {
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
}
|
||
|
||
.sku-wrap {
|
||
padding: 10rpx 20rpx;
|
||
background: #e3ad7f;
|
||
border-radius: 32rpx;
|
||
// position: absolute;
|
||
// bottom: 10rpx;
|
||
// right: 20rpx;
|
||
align-items: center;
|
||
position: relative;
|
||
|
||
.t {
|
||
font-size: 24rpx;
|
||
color: #fff;
|
||
}
|
||
|
||
.dot {
|
||
position: absolute;
|
||
top: -15rpx;
|
||
right: -10rpx;
|
||
background-color: #ff4b33;
|
||
color: #fff;
|
||
border-radius: 58rpx;
|
||
padding: 5rpx 14rpx;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 20rpx;
|
||
}
|
||
}
|
||
|
||
.Controls {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
|
||
// position: absolute;
|
||
// bottom: 10rpx;
|
||
// right: 20rpx;
|
||
.num {
|
||
margin: auto 16rpx;
|
||
}
|
||
|
||
.btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
position: relative;
|
||
|
||
.btnClick {
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
position: absolute;
|
||
// bottom: 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.lineThrough {
|
||
font-weight: normal;
|
||
text-decoration: line-through;
|
||
color: #999 !important;
|
||
font-size: 24rpx !important;
|
||
}
|
||
|
||
.money_num.lineThrough {}
|
||
}
|
||
|
||
.shop_sku {
|
||
width: 100%;
|
||
position: relative;
|
||
border-radius: 20rpx;
|
||
background: #fff;
|
||
box-sizing: border-box;
|
||
|
||
.positionabsolute {
|
||
position: absolute;
|
||
top: 30rpx;
|
||
z-index: 999;
|
||
right: 30rpx;
|
||
}
|
||
|
||
.shop_sku_name {
|
||
padding: 0 28rpx;
|
||
margin-top: 20rpx;
|
||
font-weight: bold;
|
||
font-size: 32upx;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.shop_sku_returned {
|
||
padding: 0 28rpx;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #ff534b;
|
||
}
|
||
|
||
.shop_sku_description {
|
||
padding: 0 28rpx;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
margin-top: 16rpx;
|
||
padding-bottom: 32rpx;
|
||
box-sizing: border-box;
|
||
border-bottom: 2rpx solid #f0f0f0;
|
||
}
|
||
|
||
|
||
|
||
.shop_sku_box {
|
||
padding: 20rpx;
|
||
|
||
.shop_sku_box_name {
|
||
margin-top: 20rpx;
|
||
font-weight: 500;
|
||
font-size: 28upx;
|
||
color: #333;
|
||
}
|
||
|
||
.flex-start {
|
||
.shop_sku_box_item {
|
||
margin-top: 16rpx;
|
||
padding: 12rpx 28rpx;
|
||
border-radius: 8rpx;
|
||
font-size: 24upx;
|
||
margin-right: 56rpx;
|
||
background: #efefef;
|
||
border: 2rpx solid #efefef;
|
||
position: relative;
|
||
color: #666666;
|
||
|
||
.shop_sku_box_item_tip {
|
||
width: 62rpx;
|
||
height: 47rpx;
|
||
text-align: right;
|
||
position: absolute;
|
||
top: 0;
|
||
right: 0;
|
||
background: linear-gradient(45deg, transparent, transparent 50%, #cecece 50%, #cecece 100%);
|
||
|
||
view {
|
||
font-size: 18rpx;
|
||
color: #666666;
|
||
transform: rotate(45deg);
|
||
position: absolute;
|
||
top: 5rpx;
|
||
right: 3rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.shop_sku_box_item:nth-child(1) {
|
||
margin-left: 0;
|
||
}
|
||
|
||
.disabled {
|
||
color: #999;
|
||
background-color: #f5f5f5;
|
||
border: 2rpx solid #f5f5f5;
|
||
}
|
||
|
||
.shop_sku_box_item_noselected {
|
||
color: #666;
|
||
}
|
||
|
||
.shop_sku_box_item_selected {
|
||
background: #fefaf7;
|
||
border-radius: 8rpx;
|
||
border: 2rpx solid #e8ad7b;
|
||
color: #e8ad7b;
|
||
}
|
||
}
|
||
}
|
||
|
||
.shop_skuselect {
|
||
margin-top: 16rpx;
|
||
width: 100%;
|
||
// background: #f7f7f7;
|
||
color: #999;
|
||
font-size: 24upx;
|
||
|
||
.shop_skuselectname {
|
||
color: #000;
|
||
font-size: 26upx;
|
||
}
|
||
}
|
||
|
||
.shop_bottom {
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
padding: 30rpx 28rpx;
|
||
background-color: #fff;
|
||
box-shadow: 0rpx -6rpx 14rpx 2rpx rgba(0, 0, 0, 0.1);
|
||
|
||
.price {
|
||
display: flex;
|
||
align-items: flex-end;
|
||
|
||
.i {
|
||
font-size: 28rpx;
|
||
color: #e8ad7b;
|
||
position: relative;
|
||
bottom: 4upx;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.num {
|
||
font-size: 42rpx;
|
||
color: #e8ad7b;
|
||
position: relative;
|
||
top: 6upx;
|
||
padding: 0 4upx;
|
||
}
|
||
}
|
||
|
||
.operation-wrap {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.num {
|
||
font-size: 32upx;
|
||
padding: 0 16upx;
|
||
}
|
||
|
||
.btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
position: relative;
|
||
|
||
.btnClick {
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
position: absolute;
|
||
// bottom: 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
.addShopping {
|
||
width: 100%;
|
||
height: 96rpx;
|
||
line-height: 96rpx;
|
||
text-align: center;
|
||
background: #ccc;
|
||
border-radius: 48rpx;
|
||
font-weight: 400;
|
||
font-size: 32rpx;
|
||
color: #ffffff;
|
||
margin-top: 36rpx;
|
||
}
|
||
|
||
.addShopping.active {
|
||
background: #e8ad7b;
|
||
}
|
||
}
|
||
}
|
||
|
||
.shop-info-wrap {
|
||
padding: 0 30rpx 50rpx;
|
||
box-sizing: border-box;
|
||
|
||
.info-wrap {
|
||
padding: 30rpx 0;
|
||
box-sizing: border-box;
|
||
|
||
.shopName {
|
||
align-self: center;
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
|
||
.info-wrap-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.row {
|
||
.col {
|
||
margin-bottom: 10rpx;
|
||
}
|
||
|
||
.l,
|
||
.t {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
}
|
||
}
|
||
}
|
||
|
||
.cart-wrap {
|
||
width: 100%;
|
||
padding: 22rpx 54rpx;
|
||
box-sizing: border-box;
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
z-index: 99;
|
||
padding-bottom: calc(env(safe-area-inset-bottom) + 1px);
|
||
background: #ffffff;
|
||
|
||
.cart-content {
|
||
display: flex;
|
||
align-items: center;
|
||
// height: 128rpx;
|
||
// padding: 0 36rpx;
|
||
box-sizing: border-box;
|
||
position: relative;
|
||
z-index: 99;
|
||
|
||
.left {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
position: relative;
|
||
|
||
.iconBox {
|
||
position: relative;
|
||
}
|
||
|
||
.icon {
|
||
width: 76rpx;
|
||
height: 88rpx;
|
||
margin-left: 22rpx;
|
||
}
|
||
|
||
.u-badge {
|
||
position: absolute;
|
||
top: -30rpx;
|
||
right: -30rpx;
|
||
background-color: #ff4b33;
|
||
color: #fff;
|
||
border-radius: 58rpx;
|
||
padding: 5rpx 14rpx;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 20rpx;
|
||
}
|
||
|
||
.i,
|
||
.num {
|
||
color: #333;
|
||
}
|
||
|
||
.i {
|
||
font-size: 28rpx;
|
||
position: relative;
|
||
top: 4upx;
|
||
margin-left: 64rpx;
|
||
}
|
||
|
||
.num {
|
||
font-size: 42upx;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
|
||
.btn {
|
||
height: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
|
||
.t {
|
||
width: 160rpx;
|
||
height: 64rpx;
|
||
line-height: 64rpx;
|
||
text-align: center;
|
||
background: #fefaf7;
|
||
border-radius: 36rpx 36rpx 36rpx 36rpx;
|
||
border: 2rpx solid $my-main-color;
|
||
font-weight: bold;
|
||
font-size: 28rpx;
|
||
color: $my-main-color;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.history_order {
|
||
background-color: #fff;
|
||
padding: 12rpx 16rpx;
|
||
font-size: 24rpx;
|
||
color: #333;
|
||
display: flex;
|
||
align-items: center;
|
||
box-shadow: 0rpx 6rpx 12rpx 2rpx rgba(0, 0, 0, 0.16);
|
||
position: fixed;
|
||
top: 50%;
|
||
right: 0;
|
||
transform: translateY(-50%);
|
||
border-radius: 100px 0 0 100px;
|
||
z-index: 20;
|
||
|
||
.img {
|
||
width: 36rpx;
|
||
margin-right: 8rpx;
|
||
height: 36rpx;
|
||
}
|
||
}
|
||
|
||
.old-price {
|
||
color: #999;
|
||
font-size: 24rpx;
|
||
text-decoration: line-through;
|
||
margin-left: 8rpx;
|
||
}
|
||
|
||
.relative {
|
||
position: relative;
|
||
}
|
||
|
||
.limitDiscount {
|
||
background-color: #fff0f0;
|
||
padding: 8rpx 24rpx;
|
||
white-space: nowrap;
|
||
text-align: center;
|
||
position: absolute;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
font-size: 24rpx;
|
||
color: #ffffff;
|
||
border-radius: 0;
|
||
z-index: 9;
|
||
color: #ff1c1c;
|
||
}
|
||
|
||
.stock_warning {
|
||
background-color: #F8F8F8;
|
||
padding: 8rpx 24rpx;
|
||
white-space: nowrap;
|
||
text-align: center;
|
||
position: absolute;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
font-size: 24rpx;
|
||
color: #333;
|
||
border-radius: 0;
|
||
z-index: 10;
|
||
}
|
||
|
||
.select_num_wrap {
|
||
width: 100vw;
|
||
height: 100vh;
|
||
position: relative;
|
||
|
||
.top_bg {
|
||
width: 100%;
|
||
height: 100%;
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
z-index: 1;
|
||
}
|
||
|
||
.sn-bnottom {
|
||
width: 90vw;
|
||
border-radius: 20upx;
|
||
background-color: #fff;
|
||
position: absolute;
|
||
left: 5vw;
|
||
bottom: 20vw;
|
||
z-index: 2;
|
||
|
||
.sn-header {
|
||
height: 120upx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
border-bottom: 1px solid #ececec;
|
||
padding: 0 28upx;
|
||
|
||
.t1 {
|
||
color: #333;
|
||
font-size: 32upx;
|
||
}
|
||
|
||
.t2 {
|
||
color: #999;
|
||
font-size: 28upx;
|
||
}
|
||
}
|
||
|
||
.sn-num-wrap {
|
||
padding: 38upx 28upx;
|
||
border-bottom: 1px solid #ececec;
|
||
|
||
.sn-num {
|
||
display: grid;
|
||
grid-template-columns: repeat(5, 1fr);
|
||
gap: 14px;
|
||
|
||
.item {
|
||
height: 40px;
|
||
border-radius: 6px;
|
||
background-color: #fef4eb;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
&.active {
|
||
background-color: #e8ad7b;
|
||
|
||
.t {
|
||
color: #fff;
|
||
}
|
||
}
|
||
|
||
.t {
|
||
color: #333333;
|
||
font-size: 32upx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.input {
|
||
display: flex;
|
||
padding-top: 28upx;
|
||
}
|
||
}
|
||
|
||
.sn-footer-wrap {
|
||
display: flex;
|
||
gap: 28upx;
|
||
padding: 28upx;
|
||
|
||
.btn {
|
||
flex: 1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.new-user-discount {
|
||
margin-top: 32rpx;
|
||
color: #ff1c1c;
|
||
font-weight: 700;
|
||
padding-left: 20rpx;
|
||
}
|
||
|
||
.fullAmount-activity {
|
||
position: absolute;
|
||
bottom: 100%;
|
||
left: 0;
|
||
font-size: 28rpx;
|
||
right: 0;
|
||
color: #666666;
|
||
background: linear-gradient(90deg, #ffdfe9 0%, #fef4ea 100%);
|
||
padding: 8rpx 78rpx 8rpx 42rpx;
|
||
|
||
.price {
|
||
color: #ff1c1c;
|
||
}
|
||
}
|
||
|
||
.allDiscountMoney {
|
||
color: #ff1c1c;
|
||
font-size: 12px;
|
||
margin-left: 20rpx;
|
||
}
|
||
|
||
.recommand-goods {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
margin-top: 24rpx;
|
||
|
||
.item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
margin-right: 30rpx;
|
||
margin-bottom: 30rpx;
|
||
width: 210rpx;
|
||
|
||
&:nth-child(3n) {
|
||
margin-right: 0;
|
||
}
|
||
|
||
.name {
|
||
height: 84rpx;
|
||
}
|
||
|
||
.info {
|
||
width: 100%;
|
||
}
|
||
}
|
||
}
|
||
</style> |