1931 lines
49 KiB
Vue
1931 lines
49 KiB
Vue
<template>
|
||
<view>
|
||
<Nav v-if="store.scrollTop>=44" />
|
||
<!-- 顶部面板 -->
|
||
<view class="top--panel">
|
||
<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">
|
||
{{ shopInfo.shopName }}
|
||
</view>
|
||
<view class="paneltow">
|
||
距离您{{ distance }}
|
||
</view>
|
||
<view class="panelthere flex-between">
|
||
<view class="paneltheretext">
|
||
营业时间:{{ (shopInfo.businessStartDay || '--') +' 至 '+ (shopInfo.businessEndDay || '--') +' '+ (shopInfo.businessTime || '')}}
|
||
</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">
|
||
<image class="panelfiveitemimage" :src="item.coverImg" mode="aspectFill"></image>
|
||
<view class="panelfiveitemone">
|
||
{{ item.name }}
|
||
</view>
|
||
<view class="panelfiveitemtow">
|
||
本店回头客第{{index+1}}名
|
||
</view>
|
||
<view class="panelfiveitemthere flex-start">
|
||
<text>招牌</text>
|
||
</view>
|
||
<!-- <view class="panelfiveitemfour">
|
||
{{item.shortTitle?item.shortTitle:''}}
|
||
</view>
|
||
<view class="panelfiveitemfive">
|
||
月售{{item.stockNumber}}
|
||
</view> -->
|
||
<view v-if="item.isSoldStock == 1 || item.isSaleTime == 0" 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}}</text>
|
||
<!-- 原价 -->
|
||
<text class="originalprice" v-if="item.originPrice">¥{{item.originPrice}}</text>
|
||
<!-- 单位 -->
|
||
<text class="unit" v-if="item.unitName">/{{item.unitName}}</text>
|
||
</view>
|
||
</view>
|
||
<view class="panelfiveitemNum">
|
||
<view class="sku-wrap flex-center" style="background-color: #CECECE;">
|
||
<text class="t" v-if="item.isSaleTime == 0">非可售时间</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;">
|
||
<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}}</text>
|
||
<!-- 原价 -->
|
||
<text class="originalprice" v-if="item.originPrice">¥{{item.originPrice}}</text>
|
||
<!-- 单位 -->
|
||
<text class="unit" v-if="item.unitName">/{{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" 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" @click.stop="shoppingcart(item,index,'-','单')">
|
||
</view>
|
||
</view>
|
||
<text class="num"> {{ ifcartNumber(item) }} </text>
|
||
<text class="dot num"
|
||
v-if="item.suitNum>1">{{item.suitNum<99?item.suitNum:'99+'}}</text>
|
||
<view class="btn">
|
||
<up-icon name="plus-circle-fill" color="#E9AB7A" size="25"></up-icon>
|
||
<view class="btnClick" @click.stop="shoppingcart(item,index,'+','单')">
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
|
||
</view>
|
||
<view v-if="item.isSoldStock == 1 || item.isSaleTime == 0"
|
||
style="width: 100%;height: 100%;position: absolute;top: 0;left: 0;z-index: 9,background-color: rgba(255,255,255,0.5);">
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 滚动区域 -->
|
||
<view class="scroll-panel" id="scroll-panel">
|
||
<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`}">
|
||
<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_300,h_300':''}`"
|
||
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 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="describe"> {{item1.shortTitle?item1.shortTitle:''}} </view>
|
||
|
||
<view v-if="item1.isSoldStock == 1 || item1.isSaleTime == 0" class="flex-between">
|
||
<view class="money">
|
||
<view>¥</view>
|
||
<text class="money_num"
|
||
v-if="shopInfo.isVip ==1 && shopInfo.isMemberPrice==1"
|
||
style="margin-right: 10rpx;">{{ item1.memberPrice }}</text>
|
||
<view v-if="shopInfo.isVip ==1 && shopInfo.isMemberPrice==1"
|
||
:class="{lineThrough: shopInfo.isVip ==1 && shopInfo.isMemberPrice==1}">
|
||
¥
|
||
</view>
|
||
<text class="money_num"
|
||
:class="{lineThrough: shopInfo.isVip ==1 && shopInfo.isMemberPrice==1}">{{ 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">非可售时间</text>
|
||
<text class="t" v-else-if="item1.isSoldStock == 1">已售罄</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-else class="flex-between">
|
||
<view class="money">
|
||
<view>¥</view>
|
||
<text class="money_num"
|
||
v-if="shopInfo.isVip ==1 && shopInfo.isMemberPrice==1"
|
||
style="margin-right: 10rpx;">{{ item1.memberPrice }}</text>
|
||
<view v-if="shopInfo.isVip ==1 && shopInfo.isMemberPrice==1"
|
||
:class="{lineThrough: shopInfo.isVip ==1 && shopInfo.isMemberPrice==1}">
|
||
¥
|
||
</view>
|
||
<text class="money_num"
|
||
:class="{lineThrough: shopInfo.isVip ==1 && shopInfo.isMemberPrice==1}">{{ item1.salePrice }}</text>
|
||
<text v-if="item1.unitName">/{{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" 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 != '0'">
|
||
<up-icon name="minus-circle-fill" color="#E9AB7A" size="25"></up-icon>
|
||
<view class="btnClick" @click.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" @click.stop="singleclick(item1,'+')">
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
<view v-if="item1.isSoldStock != 0 || item1.isSale == 0"
|
||
style="width: 100%;height: 100%;position: absolute;top: 0;left: 0;z-index: 9background-color: rgba(255,255,255,0.5);">
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="fill-last" :style="{ 'height':fillHeight + 'px' }"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 店铺详情 -->
|
||
<shopindex ref="showShopInfoRef"></shopindex>
|
||
<!-- 购物车 -->
|
||
<shoppingCartes :cartLists_count="cartLists_count" :cartList="matchedProducts" :showCart="showCart"
|
||
@customevent='websocketsendMessage' @close="showCart = !showCart">
|
||
</shoppingCartes>
|
||
|
||
<!-- 购物车 -->
|
||
<view class="cart-wrap" v-if="cartLists_count>0">
|
||
<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="showCart = !showCart">
|
||
</image>
|
||
<text class="u-badge"> {{cartLists_count<99?cartLists_count:'99+'}} </text>
|
||
</view>
|
||
|
||
<text class="i">¥</text>
|
||
<!-- <text class="num"
|
||
v-if="shopInfo.isVip == 1 && cartLists.memberAmount > 0">{{cartLists.memberAmount||'0.00'}}</text>
|
||
<text class="num" v-else>{{cartLists.amount||'0.00'}}</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"
|
||
:safeAreaInsetBottom='false'>
|
||
<view class="shop_sku" style="max-height:70vh;">
|
||
<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.isPauseSale == 1">
|
||
<view>售罄</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-else>
|
||
<view class="shop_sku_box">
|
||
<view class="shop_sku_box_name">
|
||
{{specifications.groupSnap.count }} 选 {{specifications.groupSnap.number }}
|
||
</view>
|
||
<view class="flex-start">
|
||
<view class="shop_sku_box_item" v-for="(option,goodsid) in specifications.groupSnap.goods"
|
||
:key="goodsid" @click="goodsidClick(option, goodsid)"
|
||
:class="{ shop_sku_box_item_selected: isOptionSelected(option)}"
|
||
:disabled="isMaxSelected() &&!isOptionSelected(option)">
|
||
{{option.proName}}/{{option.skuName}}
|
||
<view class="shop_sku_box_item_tip" v-if="specifications.item.isPauseSale == 1">
|
||
<view>售罄</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="shop_bottom">
|
||
<view class="flex-between">
|
||
<view class="price">
|
||
<text class="i">¥</text>
|
||
<text
|
||
class="num">{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?specifications.item.memberPrice:specifications.item.salePrice}}</text>
|
||
<text class="i">/{{specifications.item.unitName}}</text>
|
||
</view>
|
||
<view class="operation-wrap">
|
||
<view class="btn">
|
||
<up-icon name="minus-circle-fill" color="#E9AB7A" size="25"></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 class="addShopping" :class="(shopCartNumber>0&&canSubmit)?'active':''"
|
||
@click="submitSelection()">
|
||
{{skuBtnText}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</up-popup>
|
||
|
||
<!-- <view>
|
||
<button @click="manualClose">手动关闭连接</button>
|
||
<p>连接状态: {{ isConnected ? '已连接' : '未连接' }}</p>
|
||
<view>收到的消息:</view>
|
||
<view>
|
||
<view v-for="(message, index) in receivedMessages" :key="index">{{ message }}</view>
|
||
</view>
|
||
</view> -->
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {
|
||
ref,
|
||
reactive,
|
||
onMounted,
|
||
watchEffect,
|
||
getCurrentInstance,
|
||
computed
|
||
} from "vue";
|
||
|
||
import {
|
||
onLoad,
|
||
onReady,
|
||
onShow,
|
||
onPageScroll
|
||
} from '@dcloudio/uni-app'
|
||
|
||
//导航栏
|
||
import Nav from '@/components/CustomNavbar.vue';
|
||
import shopindex from './components/shopindex.vue'
|
||
import shoppingCartes from './components/shoppingCartes.vue'
|
||
// 获取全局属性
|
||
const {
|
||
proxy
|
||
} = getCurrentInstance();
|
||
|
||
//接口引入
|
||
import {
|
||
productminiApphotsquery,
|
||
APIgroupquery,
|
||
APIminiAppinfo,
|
||
APIminiAppskuinfo
|
||
} from "@/common/api/product/product.js";
|
||
|
||
// websocket
|
||
import useWebSocket from '@/common/js/websocket.js';
|
||
|
||
// pinia管理
|
||
import {
|
||
useNavbarStore
|
||
} from '@/stores/navbarStore';
|
||
const store = useNavbarStore();
|
||
|
||
|
||
import {
|
||
productStore
|
||
} from '@/stores/user.js';
|
||
|
||
const userStore = productStore();
|
||
|
||
// 动态更新导航栏配置
|
||
store.updateNavbarConfig({
|
||
showBack: true, //左边返回键
|
||
rightText: '', //右边文字
|
||
showSearch: true, //true是标题其他事文字
|
||
title: '',
|
||
isTransparent: false,
|
||
hasPlaceholder: false //是否要占位符
|
||
});
|
||
|
||
const userInfo = uni.cache.get('userInfo')
|
||
const shopInfo = uni.cache.get('shopInfo')
|
||
const shopTable = uni.cache.get('shopTable')
|
||
const distance = uni.cache.get('distance') //距离
|
||
|
||
|
||
//店铺详情
|
||
const showShopInfoRef = ref(null)
|
||
|
||
//调用shop组件
|
||
const callChildMethod = () => {
|
||
if (showShopInfoRef.value) {
|
||
showShopInfoRef.value.childMethod();
|
||
}
|
||
}
|
||
|
||
const shopExtend = uni.cache.get('shopTable').shopExtendMap.index_bg
|
||
|
||
// 计算高度
|
||
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(0)
|
||
|
||
//距离顶部的高度
|
||
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: {
|
||
goods: []
|
||
}
|
||
})
|
||
|
||
/* 价格 */
|
||
const salePrice = computed(() => {
|
||
// return shopInfo.isVip == 1 && memberPrice > 0 ? res.data.memberPrice : res.data.salePrice
|
||
return 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 对象,将当前规格类型的选中值设置为用户点击的选项
|
||
selectedSpecs.value = {
|
||
...selectedSpecs.value,
|
||
[specType]: option
|
||
};
|
||
if (allSpecsSelected.value) {
|
||
try {
|
||
let result = await APIminiAppskuinfo({
|
||
specInfo: selectedSpecsStr.value,
|
||
id: specifications.item.id
|
||
});
|
||
specifications.sku_id = result.id
|
||
specifications.product_id = result.productId
|
||
specifications.item = Object.assign({}, result, specifications.item);
|
||
if (result.isPauseSale == 0) {
|
||
canSubmit.value = true;
|
||
skuBtnText.value = '添加到购物车'
|
||
}
|
||
} catch (error) {
|
||
canSubmit.value = false;
|
||
}
|
||
} else {
|
||
canSubmit.value = false;
|
||
}
|
||
};
|
||
|
||
// 存储选中的选项
|
||
const selectedOptions = ref([]);
|
||
|
||
// 选择规格的方法
|
||
const goodsidClick = (option, goodsid) => {
|
||
if (isOptionSelected(option)) {
|
||
// 如果已经选中,取消选中
|
||
selectedOptions.value = selectedOptions.value.filter(item => item.proId !== option.proId);
|
||
} else if (!isMaxSelected()) {
|
||
// 如果未达到最大选择数量,添加到选中列表
|
||
selectedOptions.value.push(option);
|
||
}
|
||
};
|
||
|
||
// 判断选项是否已选中
|
||
const isOptionSelected = (option) => {
|
||
return selectedOptions.value.some(item => item.proId == option.proId);
|
||
};
|
||
|
||
// 判断是否达到最大选择数量
|
||
const isMaxSelected = () => {
|
||
// 初始他为可点击
|
||
if (selectedOptions.value.length >= specifications.groupSnap.number) {
|
||
canSubmit.value = true;
|
||
} else {
|
||
canSubmit.value = false;
|
||
}
|
||
return selectedOptions.value.length >= specifications.groupSnap.number;
|
||
};
|
||
|
||
// 计算属性,将 selectedSpecs 转换为字符串形式
|
||
const selectedSpecsStr = computed(() => {
|
||
const values = Object.values(selectedSpecs.value);
|
||
return values.join(',');
|
||
});
|
||
|
||
//添加购物车数量
|
||
const shopCartNumber = ref(0)
|
||
|
||
// 多规格 去添加购物车
|
||
const shopCart = (i) => {
|
||
if (i == '+') {
|
||
shopCartNumber.value++;
|
||
} else {
|
||
shopCartNumber.value--;
|
||
}
|
||
}
|
||
|
||
// 使用 find 方法查找购物车是否有匹配的数组
|
||
const matchingProduct = async (data) => {
|
||
return matchedProducts.value.find(product => {
|
||
if (data.type === 'single') {
|
||
return product.skuId == data.skuId && product.id == data.id
|
||
} else {
|
||
return product.skuId == data.sku_id && product.id == data.product_id
|
||
}
|
||
});
|
||
}
|
||
|
||
// 提交选择并执行下一步操作的方法
|
||
const submitSelection = async () => {
|
||
if (!canSubmit.value) {
|
||
return false;
|
||
}
|
||
let res = await matchingProduct(specifications)
|
||
if (res) {
|
||
await calculateValue(res.cartNumber, '+', shopCartNumber.value)
|
||
}
|
||
// 是否是套餐 有就传
|
||
if (selectedOptions.value) {
|
||
specifications.groupSnap.goods = selectedOptions.value
|
||
}
|
||
websocketsendMessage({
|
||
type: 'shopping',
|
||
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: specifications.groupSnap
|
||
})
|
||
showShopsku.value = false
|
||
// 这里可以添加更多的业务逻辑,例如发送请求到后端等
|
||
}
|
||
|
||
//获取多规格数据
|
||
const clickspecifications = async (item, index, indexs, type) => {
|
||
console.log(item, index, indexs, type)
|
||
// 数量清零
|
||
shopCartNumber.value = 0
|
||
// 初始化
|
||
let data = {
|
||
item: item,
|
||
index: '',
|
||
inedxs: '',
|
||
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 = item.id
|
||
specifications.sku_id = item.skuId
|
||
specifications.groupSnap = res.groupSnap[0]
|
||
}
|
||
// 购物车是否有商品
|
||
specifications.item.cartListId = await matchingProduct(specifications.item) ? item.cartListId : ''
|
||
specifications.index = index
|
||
specifications.indexs = indexs
|
||
specifications.type = type
|
||
specifications.item.selectSpecInfo = Object.fromEntries(
|
||
Object.entries(specifications.item.selectSpecInfo).filter(([_, value]) => value.length > 0)
|
||
);
|
||
// 给默认数量
|
||
specifications.item.amountcartNumber = 0
|
||
showShopsku.value = true
|
||
}
|
||
|
||
// 单规格
|
||
const singleclick = async (item, i) => {
|
||
if (selectedOptions.value.length > 0) {
|
||
specifications.groupSnap.goods = selectedOptions.value
|
||
}
|
||
// 判断购物车是否有该选中商品
|
||
let res = await matchingProduct(item)
|
||
console.log(res)
|
||
websocketsendMessage({
|
||
id: res ? item.cartListId : '',
|
||
type: 'shopping',
|
||
table_code: uni.cache.get('tableCode'),
|
||
shop_id: uni.cache.get('shopId'),
|
||
operate_type: await calculateValue(item.cartNumber, i) == 'del' ? 'del' : res ? 'edit' : 'add',
|
||
product_id: item.id,
|
||
sku_id: item.skuId,
|
||
number: await calculateValue(item.cartNumber, i),
|
||
pro_group_info: specifications.groupSnap,
|
||
})
|
||
}
|
||
|
||
// 封装加法函数
|
||
const calculateValue = (cartNumber, i, step = 1) => {
|
||
if (i == '+') {
|
||
const result = parseFloat(cartNumber) + step;
|
||
return result.toFixed(2);
|
||
} else {
|
||
// 当减到0返回del
|
||
const result = parseFloat(cartNumber) - 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 {
|
||
isConnected,
|
||
sendMessage,
|
||
closeSocket: manualClose,
|
||
receivedMessages
|
||
} = useWebSocket(options);
|
||
|
||
|
||
//购物车显示
|
||
const showCart = ref(false)
|
||
|
||
// 购物车数组
|
||
const cartList = ref([])
|
||
|
||
// 更新商品数量的方法
|
||
const updateProductQuantities = () => {
|
||
// 遍历购物车数组
|
||
if (cartListFilter.value.length > 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
|
||
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
|
||
}
|
||
});
|
||
});
|
||
} else {
|
||
shopProductList.hots.forEach((i) => {
|
||
i.cartNumber = 0
|
||
})
|
||
// 遍历商品列表二维数组
|
||
shopProductList.productInfo.forEach((group) => {
|
||
group.productList.forEach((product) => {
|
||
product.cartNumber = 0
|
||
});
|
||
});
|
||
}
|
||
}
|
||
|
||
//websocket产值
|
||
const websocketsendMessage = (data) => {
|
||
sendMessage(data)
|
||
}
|
||
|
||
// 监听接收到的消息变化
|
||
watchEffect(async () => {
|
||
if (isDataLoaded.value && receivedMessages.value.length > 0) {
|
||
const Message = receivedMessages.value[receivedMessages.value.length - 1];
|
||
if (Message) {
|
||
// 心跳返回 过滤
|
||
if (Message.type == "p") {
|
||
return false
|
||
}
|
||
|
||
// 清空购物车
|
||
if (Message.operate_type == 'shopping_cleanup') {
|
||
cartList.value = []
|
||
showCart.value = false
|
||
}
|
||
|
||
if (Message.type == 'bc') {
|
||
console.log(Message)
|
||
}
|
||
|
||
// 初始化购物车数据
|
||
if (Message.operate_type == "shopping_init") {
|
||
cartList.value = Message.data
|
||
}
|
||
|
||
// 删除除购物车
|
||
if (Message.operate_type == 'shopping_del') {
|
||
cartList.value = cartList.value.filter(item => item.id !== Message.data.id);
|
||
}
|
||
|
||
// 添加或者减少购物后返回
|
||
if (Message.operate_type == 'shopping_add' || Message.operate_type == 'sopping_edit' || Message.type == 'bc') {
|
||
[Message.data].forEach((objA) => {
|
||
const index = cartList.value.findIndex((objB) => objB.id == objA.id);
|
||
if (index !== -1) {
|
||
cartList.value[index] = objA;
|
||
} else {
|
||
cartList.value.push(objA);
|
||
}
|
||
});
|
||
}
|
||
|
||
//除去p 每次返回都回执消息
|
||
await websocketsendMessage({
|
||
type: 'receipt',
|
||
msg_id: Message.msg_id
|
||
})
|
||
|
||
// if(Message.status != 1){
|
||
// uni.showToast({
|
||
// title:'操作失败请稍后重试~'
|
||
// })
|
||
// }
|
||
|
||
// 初始化商品数量
|
||
await updateProductQuantities()
|
||
|
||
}
|
||
}
|
||
})
|
||
|
||
// 更新购物车数据
|
||
const matchedProducts = computed(() => {
|
||
return cartList.value.map((cartItem) => {
|
||
for (const group of shopProductList.productInfo) {
|
||
for (const product of group.productList) {
|
||
if (product.id == cartItem.product_id) {
|
||
console.log(cartItem, product)
|
||
// 找到匹配的商品,添加 cartListId 属性
|
||
return {
|
||
...product,
|
||
// cartListinfo:cartItem
|
||
cartListId: cartItem.id,
|
||
cartNumberToAdd: product.type == 'weight' ? 1 : cartItem.number //增加一个数量算法
|
||
};
|
||
}
|
||
}
|
||
}
|
||
// 如果没找到匹配的商品,返回 null 或者其他默认值,这里返回 null
|
||
return null;
|
||
}).filter(item => item !== null);
|
||
})
|
||
|
||
// 计算购物车商品总数量
|
||
const cartLists_count = computed(() => {
|
||
return matchedProducts.value.reduce((sum, item) => {
|
||
// 将 cartNumberToAdd 转换为数字
|
||
const num = typeof item.cartNumberToAdd === 'string' ? parseFloat(item.cartNumberToAdd) : item
|
||
.cartNumberToAdd;
|
||
return sum + num;
|
||
}, 0);
|
||
});
|
||
|
||
// 定义 ifcartNumber 计算属性方法 展示数量
|
||
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(() => {
|
||
console.log(cartList.value)
|
||
// 使用 reduce 方法对 cartList 进行处理
|
||
const grouped = cartList.value.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 orderdetail = () => {
|
||
|
||
if (this.cartLists.data.length == 0) {
|
||
uni.showToast({
|
||
title: '请先添加商品',
|
||
icon: 'none'
|
||
})
|
||
return false
|
||
}
|
||
|
||
}
|
||
|
||
// 列表请求
|
||
const productqueryProduct = async () => {
|
||
shopProductList.hots = await productminiApphotsquery()
|
||
shopProductList.productInfo = await APIgroupquery()
|
||
//第一步:将所有商品的 cartNumber 初始化为 0
|
||
shopProductList.productInfo.forEach((group) => {
|
||
group.productList.forEach((product) => {
|
||
product.cartNumber = 0;
|
||
});
|
||
});
|
||
shopProductList.hots.forEach((i) => {
|
||
i.cartNumber = 0
|
||
})
|
||
scrollTopSize.value = 0
|
||
topArr.value = []
|
||
userStore.actionsAPIuser()
|
||
userInfo.value = uni.cache.get('userInfo')
|
||
// 数据可以更新
|
||
isDataLoaded.value = true;
|
||
}
|
||
|
||
onLoad(async (e) => {
|
||
await proxy.$onLaunched;
|
||
})
|
||
|
||
onMounted(async () => {
|
||
await productqueryProduct()
|
||
setTimeout(() => {
|
||
getElementTop()
|
||
}, 500)
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.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;
|
||
}
|
||
|
||
.panelfiveitemone {
|
||
margin-top: 32rpx;
|
||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||
font-weight: 500;
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
}
|
||
|
||
.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 {
|
||
.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;
|
||
|
||
.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 {
|
||
.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;
|
||
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;
|
||
margin-left: 2px;
|
||
}
|
||
|
||
.goodsImg {
|
||
width: 200rpx;
|
||
height: 200rpx;
|
||
border-radius: 18rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.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;
|
||
|
||
}
|
||
|
||
.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: 24rpx;
|
||
color: #333;
|
||
display: flex;
|
||
align-items: flex-end;
|
||
|
||
.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;
|
||
overflow-y: auto;
|
||
padding-bottom: 320rpx;
|
||
box-sizing: border-box;
|
||
|
||
.positionabsolute {
|
||
position: absolute;
|
||
top: 30rpx;
|
||
right: 30rpx;
|
||
}
|
||
|
||
.shop_skucimage {
|
||
width: 100%;
|
||
height: 500rpx !important;
|
||
border-radius: 20rpx 20rpx 0 0;
|
||
}
|
||
|
||
.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: 0 28rpx;
|
||
|
||
.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;
|
||
// background-color: #CECECE;
|
||
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: #E7AE7B;
|
||
border-radius: 36rpx 36rpx 36rpx 36rpx;
|
||
border: 2rpx solid #E8AD7B;
|
||
font-weight: bold;
|
||
font-size: 28rpx;
|
||
color: #FFFFFF;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |