3246 lines
89 KiB
Vue
3246 lines
89 KiB
Vue
<template>
|
||
<view>
|
||
<Nav />
|
||
<!-- 顶部面板 -->
|
||
<view class="top--panel" :class="{ grayscale: !isBusinessTime }">
|
||
<image
|
||
class="panelimgbackground"
|
||
:src="
|
||
shopExtend
|
||
? shopExtend.value
|
||
: 'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/shopDetails/topBanner.png'
|
||
"
|
||
mode="aspectFill"
|
||
></image>
|
||
<view class="panelone flex-start">
|
||
<view class="u-flex u-flex-y-center">
|
||
<text>
|
||
{{ shopInfo.shopName }}
|
||
</text>
|
||
<view class="u-flex u-flex-y-center u-m-t-4">
|
||
<up-icon name="arrow-right" color="#999999" size="14"></up-icon>
|
||
</view>
|
||
</view>
|
||
<!-- <up-icon name="arrow-right" color="#999999" size="14"></up-icon> -->
|
||
</view>
|
||
<view class="paneltow" v-if="distance">距离您{{ distance }}</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="limitDiscount" v-if="showLimitDiscount(item)"
|
||
>限时折扣</view
|
||
>
|
||
<image
|
||
class="panelfiveitemimage"
|
||
:src="item.coverImg"
|
||
mode="aspectFill"
|
||
></image>
|
||
<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="panelfiveitemone">
|
||
{{ item.name }}
|
||
</view>
|
||
<view class="panelfiveitemtow"
|
||
>本店回头客第{{ index + 1 }}名</view
|
||
>
|
||
<view class="panelfiveitemthere flex-between">
|
||
<text>招牌</text>
|
||
<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">
|
||
{{
|
||
shopInfo.isVip == 1 && shopInfo.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="limitTimeDiscountRes"
|
||
: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>
|
||
</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="
|
||
$u.throttle(() => singleclick(item, '-'), 500)
|
||
"
|
||
></view>
|
||
</view>
|
||
<text class="num">{{ ifcartNumber(item) }}</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>
|
||
</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="index1"
|
||
>
|
||
<image
|
||
class="goodsImg"
|
||
v-if="item1.coverImg != null"
|
||
:lazy-load="true"
|
||
@load="imageLoaded(item1, index, index1)"
|
||
: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="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="limitDiscount" v-else-if="showLimitDiscount(item1)"
|
||
>限时折扣</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="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">
|
||
{{
|
||
shopInfo.isVip == 1 && shopInfo.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="limitTimeDiscountRes"
|
||
:cart="item1"
|
||
:shopUserInfo="shopUserInfo"
|
||
:shopInfo="shopInfo"
|
||
></GoodsPrice>
|
||
</view>
|
||
<text class="money_num" v-if="item1.unitName"
|
||
>/{{ item1.unitName }}</text
|
||
>
|
||
<text class="old-price">¥{{ 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>
|
||
</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>
|
||
|
||
<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>
|
||
</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="limitTimeDiscountRes"
|
||
@customevent="websocketsendMessage"
|
||
@close="showCart = !showCart"
|
||
:orderinfo="orderinfo"
|
||
@clickcancelOrder="clickcancelOrder"
|
||
v-if="cartLists_count > 0"
|
||
></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">{{ totalPrices }}</text>
|
||
</view>
|
||
<view class="btn" @tap="$u.debounce(orderdetail, 500)">
|
||
<text class="t">结算</text>
|
||
</view>
|
||
</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"
|
||
height="250"
|
||
></up-swiper>
|
||
<view class="shop_sku_name">{{ specifications.item.name }}</view>
|
||
<view class="shop_sku_description">
|
||
{{
|
||
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:
|
||
selectedSpecs[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>
|
||
</scroll-view>
|
||
<view class="shop_bottom">
|
||
<view class="flex-between">
|
||
<view
|
||
class="price"
|
||
v-if="
|
||
specifications.item.type != 'package' &&
|
||
specifications.item.result
|
||
"
|
||
>
|
||
<text class="i">¥</text>
|
||
<view class="num">
|
||
<GoodsPrice
|
||
:limitDiscount="limitTimeDiscountRes"
|
||
:cart="specifications.item.result"
|
||
:shopUserInfo="shopUserInfo"
|
||
:shopInfo="shopInfo"
|
||
></GoodsPrice>
|
||
</view>
|
||
|
||
<text class="num" v-if="false">
|
||
|
||
{{
|
||
shopInfo.isVip == 1 && shopInfo.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" v-else>
|
||
<text class="i">¥</text>
|
||
<view class="num">
|
||
<GoodsPrice
|
||
:limitDiscount="limitTimeDiscountRes"
|
||
:cart="specifications.item"
|
||
:shopUserInfo="shopUserInfo"
|
||
:shopInfo="shopInfo"
|
||
></GoodsPrice>
|
||
</view>
|
||
<text class="num" v-if="false">
|
||
{{
|
||
shopInfo.isVip == 1 && shopInfo.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'"
|
||
>
|
||
<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>
|
||
<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>
|
||
</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>
|
||
</template>
|
||
|
||
<script setup>
|
||
//价格计算辅助函数
|
||
import * as orderUtils from "@/utils/order-utils.js";
|
||
import BigNumber from "bignumber.js";
|
||
|
||
import GoodsPrice from "@/components/goods-price.vue";
|
||
|
||
import * as limitTimeDiscountapi from "@/common/api/market/limitTimeDiscount.js";
|
||
import ModalList from "@/components/modal-list.vue";
|
||
import recommendGoodsModal from "./components/recommend-goods-modal.vue";
|
||
import {
|
||
ref,
|
||
reactive,
|
||
onMounted,
|
||
watchEffect,
|
||
getCurrentInstance,
|
||
computed,
|
||
provide,
|
||
watch,
|
||
} from "vue";
|
||
|
||
import {
|
||
onLoad,
|
||
onReady,
|
||
onShow,
|
||
onHide,
|
||
onPageScroll,
|
||
} from "@dcloudio/uni-app";
|
||
|
||
//导航栏
|
||
import Nav from "@/components/CustomNavbar.vue";
|
||
import shopindex from "./components/shopindex.vue";
|
||
import shoppingCartes from "./components/shoppingCartes.vue";
|
||
import confirmorder from "./components/confirmorder.vue";
|
||
import Loading from "@/components/Loading.vue";
|
||
import dayjs from "dayjs";
|
||
import isBetween from "dayjs/plugin/isBetween";
|
||
dayjs.extend(isBetween);
|
||
|
||
//点单智能推荐
|
||
function onBuyClick(item) {
|
||
console.log("onBuyClick", item);
|
||
console.log("shopProductList", shopProductList);
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取全局属性
|
||
const { proxy } = getCurrentInstance();
|
||
|
||
//接口引入
|
||
import {
|
||
productminiApphotsquery,
|
||
APIgroupquery,
|
||
APIminiAppinfo,
|
||
APIminiAppskuinfo,
|
||
} from "@/common/api/product/product.js";
|
||
|
||
import {
|
||
APIhistoryOrder,
|
||
APIcancelOrder,
|
||
APIrmPlaceOrder,
|
||
} from "@/common/api/order/index.js";
|
||
|
||
// websocket
|
||
// import useWebSocket from '@/common/js/websocket.js';
|
||
import { useWebSocket } from "@/stores/carts-websocket.js";
|
||
|
||
// pinia管理
|
||
import { useNavbarStore } from "@/stores/navbarStore";
|
||
|
||
// 结账管理
|
||
import { Memberpay } from "@/stores/pay.js";
|
||
|
||
const storeMemberpay = Memberpay();
|
||
const store = useNavbarStore();
|
||
|
||
import { productStore } from "@/stores/user.js";
|
||
|
||
const userStore = productStore();
|
||
|
||
// 金额管理
|
||
import { useCartStore } from "@/stores/order.js";
|
||
const cartStore = useCartStore();
|
||
|
||
// 动态更新导航栏配置
|
||
store.updateNavbarConfig({
|
||
showBack: true, //左边返回键
|
||
rightText: "", //右边文字
|
||
showSearch: false, //true是标题其他事文字
|
||
title: "",
|
||
isTransparent: false,
|
||
hasPlaceholder: false, //是否要占位符
|
||
});
|
||
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 isLoading = ref(true);
|
||
|
||
//调用shop组件
|
||
const callChildMethod = () => {
|
||
if (showShopInfoRef.value) {
|
||
showShopInfoRef.value.childMethod();
|
||
}
|
||
};
|
||
|
||
try {
|
||
const shopExtend = uni.cache.get("shopTable").shopExtendMap.shopinfo_bg;
|
||
} catch (error) {}
|
||
|
||
// 计算高度
|
||
const navScroll = ref(null);
|
||
|
||
// 获取商品数据
|
||
const shopProductList = reactive({
|
||
hots: [],
|
||
productInfo: [],
|
||
});
|
||
|
||
// * 图片加载
|
||
const imageLoaded = (item, index, index1) => {
|
||
// shopProductList.productInfo[index].products[index1]['imgLoad'] = true;
|
||
};
|
||
|
||
// 计算左侧位置
|
||
const leftIndex = ref(0);
|
||
|
||
//距离顶部的高度
|
||
const scrollTopSiz = 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]);
|
||
});
|
||
|
||
// 处理规格选择的方法
|
||
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 >= 0) {
|
||
shopCartNumber.value = 0;
|
||
return false;
|
||
}
|
||
let res = await shoppingcart();
|
||
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) {
|
||
console.log(res, specifications);
|
||
if (specifications.type == "sku") {
|
||
shopCartNumber.value = parseFloat(specifications.item.result.suitNum);
|
||
} else {
|
||
shopCartNumber.value = parseFloat(specifications.item.suitNum);
|
||
}
|
||
} else {
|
||
shopCartNumber.value++;
|
||
}
|
||
}
|
||
};
|
||
|
||
// 套餐比较两个对象是否相等
|
||
function isObjectEqual(obj1, obj2) {
|
||
if (
|
||
typeof obj1 !== "object" ||
|
||
obj1 === null ||
|
||
typeof obj2 !== "object" ||
|
||
obj2 === null
|
||
) {
|
||
return obj1 === obj2;
|
||
}
|
||
const keys1 = Object.keys(obj1);
|
||
const keys2 = Object.keys(obj2);
|
||
if (keys1.length !== keys2.length) {
|
||
return false;
|
||
}
|
||
for (const key of keys1) {
|
||
if (Array.isArray(obj1[key]) && Array.isArray(obj2[key])) {
|
||
if (!isArrayEqual(obj1[key], obj2[key])) {
|
||
return false;
|
||
}
|
||
} else if (!isObjectEqual(obj1[key], obj2[key])) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// 比较两个数组是否相等(忽略顺序)
|
||
function isArrayEqual(arr1, arr2) {
|
||
if (arr1.length !== arr2.length) {
|
||
return false;
|
||
}
|
||
const usedIndices = new Array(arr2.length).fill(false);
|
||
for (const item1 of arr1) {
|
||
let found = false;
|
||
for (let i = 0; i < arr2.length; i++) {
|
||
if (!usedIndices[i] && isObjectEqual(item1, arr2[i])) {
|
||
usedIndices[i] = true;
|
||
found = true;
|
||
break;
|
||
}
|
||
}
|
||
if (!found) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// 根据购物车的数据匹配选中的商品查找是否有匹配的数组
|
||
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 (!canSubmit.value) {
|
||
return false;
|
||
}
|
||
res = await matchingProduct(specifications.item.result);
|
||
}
|
||
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;
|
||
}
|
||
if (
|
||
(specifications.item.type == "package" && allConditionsSatisfied.value) ||
|
||
(specifications.item.type == "sku" && canSubmit.value)
|
||
) {
|
||
let res = await shoppingcart();
|
||
|
||
// 是否是套餐 有就传
|
||
if (specifications.item.type == "package") {
|
||
// 需求更改:所所有商品套餐都是add,没有修改
|
||
res = null;
|
||
} else {
|
||
selectedGroupSnap.value = [];
|
||
}
|
||
|
||
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,
|
||
});
|
||
// 清空套餐选中
|
||
selectedGroupSnap.value = [];
|
||
showShopsku.value = false;
|
||
} else {
|
||
return;
|
||
}
|
||
};
|
||
|
||
//获取多规格数据
|
||
const clickspecifications = async (item, index, indexs, type) => {
|
||
console.log(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;
|
||
}
|
||
// 数量清零
|
||
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);
|
||
specifications.item = res;
|
||
if (specifications.item.type == "package") {
|
||
selectedOptions.value = [];
|
||
specifications.product_id = res.id;
|
||
specifications.sku_id = item.skuId;
|
||
shopCartNumber.value = 1;
|
||
}
|
||
// 购物车是否有商品
|
||
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;
|
||
};
|
||
// 判断商品是否在可售时间内
|
||
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;
|
||
};
|
||
|
||
// 单规格
|
||
const singleclick = async (item, i) => {
|
||
if (!isProductAvailable(item.days, item.startTime, item.endTime)) {
|
||
uni.showToast({
|
||
title: "不在可售时间内",
|
||
});
|
||
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;
|
||
}
|
||
websocketsendMessage({
|
||
id: res ? item.cartListId : "",
|
||
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,
|
||
});
|
||
};
|
||
|
||
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"),
|
||
},
|
||
};
|
||
const useSocket = useWebSocket();
|
||
useSocket.connect(options.initMessage, onMessage);
|
||
//购物车显示
|
||
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);
|
||
const sendData = { ...data, is_time_discount: 0 };
|
||
if (cartStore.limitTimeDiscount && cartStore.limitTimeDiscount.id) {
|
||
const canUse = orderUtils.canUseLimitTimeDiscount(
|
||
data,
|
||
cartStore.limitTimeDiscount,
|
||
shopInfo,
|
||
shopUserInfo.value,
|
||
"product_id"
|
||
);
|
||
console.log("canUse", canUse);
|
||
if (canUse) {
|
||
sendData.is_time_discount = 1;
|
||
}
|
||
}
|
||
delete sendData.memberPrice;
|
||
uni.$u.debounce(() => {
|
||
useSocket.sendMessage(sendData);
|
||
}, 500);
|
||
};
|
||
|
||
// 用于记录已经处理过的消息的 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,
|
||
});
|
||
}
|
||
|
||
// 收到的消息变化
|
||
async function onMessage(Message) {
|
||
if (Message) {
|
||
console.log("product index 收到消息", 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.carts = Message.data;
|
||
cartStore.limitTimeDiscount = Message.time_dis_info;
|
||
uni.hideLoading();
|
||
isLoading.value = false;
|
||
// 初始化商品数量
|
||
// setGoodsInitSel(Message.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") {
|
||
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();
|
||
},
|
||
});
|
||
}
|
||
if (Message.operate_type == "time_discount_save") {
|
||
cartStore.limitTimeDiscount = Message.data;
|
||
console.log("time_discount_save", cartStore.limitTimeDiscount);
|
||
}
|
||
|
||
//除去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 () => {
|
||
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"),
|
||
});
|
||
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 (limitTimeDiscountRes.value && limitTimeDiscountRes.value.id) {
|
||
//限时折扣
|
||
const price = orderUtils.returnPrice({
|
||
goods: item,
|
||
shopInfo,
|
||
limitTimeDiscountRes: limitTimeDiscountRes.value,
|
||
shopUserInfo: shopUserInfo.value,
|
||
idKey: "id",
|
||
});
|
||
return total + parseFloat(price) * parseFloat(item.cartNumber);
|
||
}
|
||
// 是否启用会员价 0否1是
|
||
if (shopUserInfo.isVip == 1 && shopUserInfo.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 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 ifcartNumber = computed(() => {
|
||
// return (item) => {
|
||
// // 如果 item 为空或者 cartNumber 不是字符串类型,返回 0
|
||
// if (!item || typeof item.cartNumber !== 'string') {
|
||
// return 0;
|
||
// }
|
||
// let numValue = parseFloat(item.cartNumber);
|
||
// if (isNaN(numValue)) {
|
||
// // 如果转换结果是 NaN,说明 cartNumber 不是有效的数字字符串,返回 0
|
||
// return 0;
|
||
// }
|
||
// // 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 productqueryProduct = async () => {
|
||
cartStore.goodsIsloading = false;
|
||
try {
|
||
shopProductList.hots = await productminiApphotsquery();
|
||
shopProductList.productInfo = await APIgroupquery();
|
||
} catch (error) {
|
||
uni.showToast({
|
||
title: "网络不稳定,请重新扫码进入",
|
||
icon: "none",
|
||
});
|
||
setTimeout(() => {
|
||
uni.pro.switchTab("index/index");
|
||
}, 1000);
|
||
}
|
||
if (
|
||
shopProductList.productInfo.length > 0 ||
|
||
shopProductList.hots.length > 0
|
||
) {
|
||
//TODO handle the exception
|
||
//第一步:将所有商品的 cartNumber 初始化为 0
|
||
shopProductList.productInfo.forEach((group) => {
|
||
group.productList.forEach(async (product) => {
|
||
product.cartNumber = 0;
|
||
product.isSaleTimeshow = await isProductAvailable(
|
||
product.days,
|
||
product.startTime,
|
||
product.endTime
|
||
);
|
||
cartStore.setGoodsMap(product.id, product);
|
||
});
|
||
});
|
||
shopProductList.hots.forEach(async (i) => {
|
||
i.cartNumber = 0;
|
||
i.isSaleTimeshow = await isProductAvailable(
|
||
i.days,
|
||
i.startTime,
|
||
i.endTime
|
||
);
|
||
cartStore.setGoodsMap(i.id, i);
|
||
});
|
||
|
||
cartStore.goodsIsloading = true;
|
||
scrollTopSize.value = 0;
|
||
topArr.value = [];
|
||
// userStore.actionsAPIuser()
|
||
// 数据可以更新
|
||
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);
|
||
|
||
onLoad(async (e) => {
|
||
await proxy.$onLaunched;
|
||
});
|
||
|
||
const limitTimeDiscountRes = ref(null);
|
||
|
||
function showLimitDiscount(item) {
|
||
if (!cartStore.limitTimeDiscount || !cartStore.limitTimeDiscount.id) {
|
||
return false;
|
||
}
|
||
return orderUtils.canUseLimitTimeDiscount(
|
||
item,
|
||
cartStore.limitTimeDiscount,
|
||
shopInfo,
|
||
shopUserInfo.value,
|
||
"id"
|
||
);
|
||
}
|
||
|
||
onShow(async () => {
|
||
// 监听页面显示和隐藏
|
||
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: "",
|
||
};
|
||
}
|
||
});
|
||
|
||
onHide(() => {});
|
||
|
||
onMounted(async () => {
|
||
await proxy.$onLaunched;
|
||
// 获取当前页面栈
|
||
const pages = getCurrentPages();
|
||
// 获取当前页面实例
|
||
const currentPage = pages[pages.length - 1];
|
||
// 获取页面参数
|
||
const options = currentPage.options;
|
||
let res = await APIhistoryOrder({
|
||
tableCode: uni.cache.get("tableCode"),
|
||
});
|
||
const limitRes = await limitTimeDiscountapi.getConfig({
|
||
shopId: uni.cache.get("shopId"),
|
||
});
|
||
if (limitRes && typeof limitRes == "object") {
|
||
limitTimeDiscountRes.value = limitRes;
|
||
websocketsendMessage({
|
||
type: "shopping",
|
||
operate_type: "time_discount_save",
|
||
table_code: uni.cache.get("tableCode"),
|
||
shop_id: uni.cache.get("shopId"),
|
||
operate_type: "time_discount_save",
|
||
data: limitRes,
|
||
});
|
||
} else {
|
||
websocketsendMessage({
|
||
type: "shopping",
|
||
operate_type: "time_discount_save",
|
||
table_code: uni.cache.get("tableCode"),
|
||
shop_id: uni.cache.get("shopId"),
|
||
operate_type: "time_discount_save",
|
||
data: null,
|
||
});
|
||
}
|
||
|
||
await productqueryProduct();
|
||
if (res && res.id && shopInfo.registerType == "after") {
|
||
toHistory();
|
||
return;
|
||
}
|
||
setTimeout(() => {
|
||
// 启动网络监听
|
||
useSocket.initNetworkListener();
|
||
getElementTop();
|
||
}, 500);
|
||
});
|
||
|
||
//跳转历史订单
|
||
function toHistory() {
|
||
const tableCode = uni.cache.get("tableCode");
|
||
const shopId = uni.cache.get("shopId");
|
||
uni.navigateTo({
|
||
url: `/pages/order/confirm-order?tableCode=${tableCode}&shopId=${shopId}`,
|
||
});
|
||
}
|
||
</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-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: 500;
|
||
font-size: 32rpx;
|
||
color: #333333;
|
||
}
|
||
|
||
.paneltow {
|
||
padding: 0 20rpx;
|
||
margin-top: 16rpx;
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
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: 9;
|
||
background-color: rgb(0, 0, 0, 0.5);
|
||
|
||
image {
|
||
padding: 30rpx;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
|
||
.panelfiveitemone {
|
||
margin-top: 32rpx;
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: 500;
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
overflow: hidden; //超出的文本隐藏
|
||
text-overflow: ellipsis; //溢出用省略号显示
|
||
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;
|
||
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;
|
||
padding-bottom: 250rpx;
|
||
|
||
.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:last-child {
|
||
padding-bottom: 60rpx;
|
||
}
|
||
|
||
.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);
|
||
position: fixed;
|
||
left: 0;
|
||
bottom: 0;
|
||
|
||
.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: 0 20rpx;
|
||
box-sizing: border-box;
|
||
position: fixed;
|
||
bottom: 40rpx;
|
||
left: 0;
|
||
z-index: 99;
|
||
|
||
.cart-content {
|
||
display: flex;
|
||
align-items: center;
|
||
height: 128rpx;
|
||
background: #ffffff;
|
||
box-shadow: 0rpx 0rpx 20rpx 2rpx rgba(0, 0, 0, 0.15);
|
||
border-radius: 58rpx;
|
||
padding: 0 36rpx;
|
||
box-sizing: border-box;
|
||
|
||
.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: 20upx;
|
||
position: relative;
|
||
top: 4upx;
|
||
margin-left: 64rpx;
|
||
}
|
||
|
||
.num {
|
||
font-size: 42upx;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
|
||
.btn {
|
||
height: 100%;
|
||
width: 40%;
|
||
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;
|
||
}
|
||
.limitDiscount {
|
||
background-color: #cc5617;
|
||
padding: 2rpx 10rpx;
|
||
white-space: nowrap;
|
||
text-align: center;
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #ffffff;
|
||
border-radius: 20rpx 0rpx 20rpx 0rpx;
|
||
z-index: 9;
|
||
color: #fff;
|
||
}
|
||
</style>
|