增加商品弹窗组件

This commit is contained in:
2025-12-24 17:20:42 +08:00
parent b3c1ab3b8b
commit 65554b043c
4 changed files with 751 additions and 315 deletions

View File

@@ -52,8 +52,8 @@
<view class="relative">
<image @click.stop="getProductImgs(item)" class="panelfiveitemimage" :src="item.coverImg"
mode="aspectFill"></image>
<image @click.stop="getProductImgs(item)" class="panelfiveitemimage"
:src="item.coverImg" mode="aspectFill"></image>
<view class="limitDiscount" v-if="showLimitDiscount(item)">
限时折扣{{ limitDiscountCountdown }}</view>
<!-- <view class="limitDiscount" v-if="item.is_time_discount">
@@ -151,7 +151,7 @@
<!-- <text class="dot num"
v-if="item.cartNumber > 0">{{ ifcartNumber(item) < 99 ? ifcartNumber(item) : '99+' }}</text> -->
<text class="dot num"
v-if="returnGoodsImCartNum(item)">{{ returnGoodsImCartNum(item) < 99 ? returnGoodsImCartNum(item) : '99+' }}</text>
v-if="returnGoodsImCartNum(item)">{{ returnGoodsImCartNum(item) < 99 ? returnGoodsImCartNum(item) : '99+' }}</text>
</view>
<view class="Controls" v-else>
<view class="btn" v-if="item.cartNumber != '0'">
@@ -199,8 +199,8 @@
<view class="goods" @click="clickspecifications(item1, index, index1)"
v-for="(item1, index1) in item.productList" :key="item1.id">
<view class="relative">
<image class="goodsImg" @click.stop="getProductImgs(item1)" v-if="item1.coverImg != null"
:lazy-load="true"
<image class="goodsImg" @click.stop="getProductImgs(item1)"
v-if="item1.coverImg != null" :lazy-load="true"
:src="`${item1.coverImg}${!item1.imgLoad ? '?x-oss-process=image/resize,m_lfit,w_150,h_150' : ''}`"
mode="aspectFill"></image>
<image class="goodsImg"
@@ -292,9 +292,9 @@
<text class="t" v-else>选规格</text>
<!-- <text class="dot num"
v-if="item1.cartNumber > 0">{{ ifcartNumber(item1) < 99 ? ifcartNumber(item1) : '99+' }}</text> -->
<text class="dot num"
v-if="returnGoodsImCartNum(item1)">{{ returnGoodsImCartNum(item1) < 99 ? returnGoodsImCartNum(item1) : '99+' }}</text>
<text class="dot num"
v-if="returnGoodsImCartNum(item1)">{{ returnGoodsImCartNum(item1) < 99 ? returnGoodsImCartNum(item1) : '99+' }}</text>
</view>
</view>
<view class="Controls" v-else>
@@ -442,13 +442,39 @@
</view>
</view>
</view>
<!-- 推荐搭配 -->
<view class="u-m-t-48">
<view class="u-m-t-48 u-p-30">
<view class="font-bold u-font-32 ">推荐搭配</view>
<view class="u-flex recommand-goods">
<view class=" item" v-for="(item,index) in 6" :key="index">
<up-image width="210rpx" height="210rpx" radius="12rpx"></up-image>
<view class="info">
<view class="u-line-2 name u-m-t-10 u-font-32 font-500">
商品名
</view>
<view class="u-flex u-row-between">
<view class="font-bold">
<text class="u-font-24">¥</text>
<text class="u-font-32">40</text>
</view>
<view class="btn">
<up-icon name="plus-circle-fill" color="#E9AB7A" size="25"></up-icon>
</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<!-- 占位 -->
<view style="height: 42rpx;"></view>
<view class="shop_bottom">
<view class="flex-between">
<view class="price price-sku"
@@ -545,7 +571,7 @@
<Loading :isLoading="!useSocket.isConnected" />
<ModalList></ModalList>
<recommendGoodsModal v-if="isDataLoaded" @onBuyClick="onBuyClick"></recommendGoodsModal>
<goodsModal></goodsModal>
<goodsModal v-model="showGoodsModal" :goods="specifications.item" @prveImgs="prveImgs"></goodsModal>
<xbSwiperPreview :visable="showPrveImg" :imgs="prveImgsList" @update:visable="updateShowPrveImg">
</xbSwiperPreview>
<!-- 显示选择人数popup -->
@@ -603,7 +629,8 @@
productminiApphotsquery,
APIgroupquery,
APIminiAppinfo,
APIminiAppskuinfo
APIminiAppskuinfo,
productRelated
} from '@/common/api/product/product.js';
import {
@@ -680,8 +707,8 @@
import {
useNavbarStore
} from '@/stores/navbarStore';
import {
useWebSocket
} from '@/stores/carts-websocket.js';
@@ -709,7 +736,9 @@
import {
useCartStore
} from '@/stores/order.js';
import { computed } from 'vue';
import {
computed
} from 'vue';
const cartStore = useCartStore();
/**
* store本地存储 end
@@ -760,6 +789,8 @@ import { computed } from 'vue';
/**
* 通用数据合集 start
*/
const showGoodsModal = ref(false)
// 门店信息
const shopInfo = reactive({});
Object.assign(shopInfo, uni.cache.get('shopInfo'));
@@ -810,35 +841,35 @@ import { computed } from 'vue';
};
// 购物车对应的商品数
const GoodsIDInCartNumMap=computed(()=>{
const map={}
for(let cart in cartStore.carts){
if(map[cart.product_id]){
map[cart.product_id]+=cart.number*1
}else{
map[cart.product_id]=cart.number*1
const GoodsIDInCartNumMap = computed(() => {
const map = {}
for (let cart in cartStore.carts) {
if (map[cart.product_id]) {
map[cart.product_id] += cart.number * 1
} else {
map[cart.product_id] = cart.number * 1
}
}
return map
})
/**
* 返回购物车对应的商品数量
*/
function returnGoodsImCartNum(goods){
if(GoodsIDInCartNumMap.value.hasOwnProperty([goods.id]) ){
function returnGoodsImCartNum(goods) {
if (GoodsIDInCartNumMap.value.hasOwnProperty([goods.id])) {
GoodsIDInCartNumMap.value[goods.id]
}
return 0
}
// 获取商品数据
const shopProductList = reactive({
@@ -1305,9 +1336,9 @@ import { computed } from 'vue';
//预览图
const showPrveImg = ref(false);
const prveImgsList = ref([]);
function updateShowPrveImg(e){
showPrveImg.value=e
function updateShowPrveImg(e) {
showPrveImg.value = e
}
function prveImgs(images) {
@@ -1321,14 +1352,14 @@ import { computed } from 'vue';
}
async function getProductImgs(item) {
console.log('getProductImgs',item)
console.log('getProductImgs', item)
let res = await APIminiAppinfo(item.id);
prveImgs(res.images);
}
//获取多规格数据
const clickspecifications = async (item, index, indexs, type) => {
console.log('clickspecifications',item);
console.log('clickspecifications', item);
// 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券
// if (
// item.isSoldStock == 1 ||
@@ -1386,7 +1417,8 @@ import { computed } from 'vue';
.filter(([_, value]) => value.length > 0));
// 给默认数量
specifications.item.amountcartNumber = 0;
showShopsku.value = true;
// showShopsku.value = true;
showGoodsModal.value=true
};
// 判断商品是否在可售时间内
const isProductAvailable = async (sellDaysStr, startTimeStr, endTimeStr) => {
@@ -1622,11 +1654,11 @@ import { computed } from 'vue';
function cartInit(arr) {
const result = []
console.log('cartInitArr',arr);
console.log('allGoodsArr',allGoodsArr);
console.log('cartInitArr', arr);
console.log('allGoodsArr', allGoodsArr);
cartStore.carts = arr.map(v => {
const goods = allGoodsArr.find(g => g.id == v.product_id)
const goodsSkuList = goods?goods.skuList : []
const goodsSkuList = goods ? goods.skuList : []
const findSku = goodsSkuList.find(sku => sku.id == v.sku_id)
const memberPrice = findSku ? findSku.memberPrice : 0
const is_time_discount = limitUtils.canUseLimitTimeDiscount({
@@ -1634,7 +1666,7 @@ import { computed } from 'vue';
memberPrice
}, cartStore.limitTimeDiscount, shopInfo,
shopUserInfo.value, 'product_id');
if(!goods){
if (!goods) {
useSocket.sendMessage({
id: v.id,
operate_type: "del",
@@ -1649,7 +1681,7 @@ import { computed } from 'vue';
is_time_discount: is_time_discount ? 1 : 0,
memberPrice
}
}).filter(v=>v)
}).filter(v => v)
for (let cart of arr) {
const findItem = cartStore.carts.find(v => v.id == cart.id)
@@ -1826,7 +1858,7 @@ import { computed } from 'vue';
});
}
//除去p 每次返回都回执消息
await websocketsendMessage({
@@ -2120,11 +2152,11 @@ import { computed } from 'vue';
}
return currentTime >= startTime && currentTime <= endTime;
});
let allGoodsArr=[]
let allGoodsArr = []
// 列表请求
const productqueryProduct = async () => {
cartStore.goodsIsloading = false;
allGoodsArr=[]
allGoodsArr = []
try {
shopProductList.hots = await productminiApphotsquery();
shopProductList.productInfo = await APIgroupquery();
@@ -2144,8 +2176,8 @@ import { computed } from 'vue';
group.productList.forEach(async (product) => {
product.isSaleTimeshow = await isProductAvailable(product.days, product
.startTime, product.endTime);
allGoodsArr.push(product)
allGoodsArr.push(product)
cartStore.setGoodsMap(product.id, product);
});
@@ -2156,11 +2188,11 @@ import { computed } from 'vue';
cartStore.setGoodsMap(i.id, i);
});
console.log('shopProductList', shopProductList);
if(cartStore.carts.length>0){
if (cartStore.carts.length > 0) {
cartInit(cartStore.carts)
}
cartStore.goodsIsloading = true;
scrollTopSize.value = 0;
topArr.value = [];
@@ -2415,7 +2447,7 @@ import { computed } from 'vue';
tableCode: uni.cache.get('tableCode')
});
oldOrder.value = res;
if (res && res.id && shopInfo.registerType == 'after'&&!e.noJump) {
if (res && res.id && shopInfo.registerType == 'after' && !e.noJump) {
toHistory();
return;
}
@@ -2475,8 +2507,8 @@ import { computed } from 'vue';
idKey: 'id'
});
}
function watchEmit(){
function watchEmit() {
uni.$off('updateProductIndex')
uni.$on('updateProductIndex', function(data) {
getNewUserDiscount()
@@ -2530,12 +2562,12 @@ import { computed } from 'vue';
});
if (res && typeof res == 'object') {
newUserDiscount.value = res;
cartStore.consumeDiscount=res
cartStore.newUserDiscount=res.amount
}else{
cartStore.consumeDiscount = res
cartStore.newUserDiscount = res.amount
} else {
newUserDiscount.value = null;
cartStore.consumeDiscount={}
cartStore.newUserDiscount=0
cartStore.consumeDiscount = {}
cartStore.newUserDiscount = 0
}
}
@@ -2595,8 +2627,8 @@ import { computed } from 'vue';
return 0
})
const oldOrder = ref(null);
// 限时折扣
async function getLimitDiscount() {
const limitRes = await limitTimeDiscountapi.getConfig({
@@ -3233,7 +3265,6 @@ import { computed } from 'vue';
border-radius: 20rpx;
background: #fff;
box-sizing: border-box;
padding-bottom: 200rpx;
.positionabsolute {
position: absolute;
@@ -3268,9 +3299,7 @@ import { computed } from 'vue';
border-bottom: 2rpx solid #f0f0f0;
}
.shop_sku_box:last-child {
padding-bottom: 140rpx;
}
.shop_sku_box {
padding: 20rpx;
@@ -3356,9 +3385,6 @@ import { computed } from 'vue';
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;
@@ -3734,4 +3760,31 @@ import { computed } from 'vue';
font-size: 12px;
margin-left: 20rpx;
}
.recommand-goods {
display: flex;
flex-wrap: wrap;
margin-top: 24rpx;
.item {
display: flex;
flex-direction: column;
align-items: center;
margin-right: 30rpx;
margin-bottom: 30rpx;
width: 210rpx;
&:nth-child(3n) {
margin-right: 0;
}
.name {
height: 84rpx;
}
.info {
width: 100%;
}
}
}
</style>