优化会员,商品,下单

This commit is contained in:
wwz
2025-03-15 12:03:34 +08:00
parent e6ca187e5a
commit fc957feb72
19 changed files with 484 additions and 978 deletions

View File

@@ -15,7 +15,7 @@
<view class="item">
<up--input class="num_item" v-model="otherNum" :class="{'active':numIndex==-1 }"
@input="isOtherNum" @focus="tabCut(-1)" @blur="blur()" border="none" type="nubmer"
maxlength="3"></up--input>
maxlength="3" placeholder='请输入..'></up--input>
</view>
<!-- <view class="num_item" v-else :class="{'active':numIndex==-1 }"></view> -->
</view>
@@ -33,7 +33,7 @@
ref
} from 'vue'
const otherNum = ref('其他')
const otherNum = ref('')
const numIndex = ref(0)

View File

@@ -281,8 +281,6 @@
paymentmethod.payType = e.payType;
}
// 提交订单
const orderdetail = async () => {
let res = await storeMemberpay.actionscreateOrder({

View File

@@ -19,9 +19,15 @@
</view>
<view class="info">
<view class="name"> {{ item.name }} </view>
<view class="select-sku-wrap" v-if="item.skuList">
<view class="select-sku-wrap" v-if="item.type == 'sku'">
<text v-for="i in item.skuList" :key="i.id">
{{item.id == i.productId && item.skuId == i.id ? i.specInfo :""}}
{{item.cartListinfo.sku_id == i.id? i.name:"" }}
</text>
</view>
<view class="select-sku-wrap" v-if="item.type == 'package'">
<view>{{dataprocessing(item.cartListinfo).title}}</view>
<text v-for="i in dataprocessing(item.cartListinfo).goods" :key="i.id">
{{i.proName }}
</text>
</view>
<view class="price-wrap" style="padding-top: 0;">
@@ -93,6 +99,7 @@
type: Boolean
},
});
const shopInfo = uni.cache.get('shopInfo')
// 定义 ifcartNumber 计算属性方法
@@ -138,6 +145,12 @@
})
}
const dataprocessing = computed(() => {
return (item) => {
return JSON.parse(item.pro_group_info);
};
})
// 封装加法函数
const calculateValue = (cartNumber, i, step = 1) => {
if (i == '+') {

View File

@@ -98,7 +98,8 @@
<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="singleclick(item,'-')">
<view class="btnClick"
@tap.stop="$u.throttle(() => singleclick(item, '-'), 500)">
</view>
</view>
<text class="num"> {{ ifcartNumber(item) }} </text>
@@ -106,7 +107,8 @@
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="singleclick(item,'+')">
<view class="btnClick"
@tap.stop="$u.throttle(() => singleclick(item, '+'), 500)">
</view>
</view>
</view>
@@ -161,15 +163,9 @@
<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 class="money_num" style="margin-right: 10rpx;">
{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?item1.memberPrice:item1.salePrice}}
</text>
<text v-if="item1.unitName">/{{item1.unitName}}</text>
</view>
<view class="flex-end">
@@ -182,18 +178,11 @@
<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 class="money_num" style="margin-right: 10rpx;">
{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?item1.memberPrice: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"
@@ -204,24 +193,25 @@
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 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" @click.stop="singleclick(item1,'+')">
<view class="btnClick"
@tap.stop="$u.throttle(() => singleclick(item1, '+'), 500)">
</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>
@@ -232,10 +222,12 @@
</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>
<!-- 购物车 -->
@@ -244,7 +236,7 @@
</shoppingCartes>
<!-- 显示购物车栏 -->
<view class="cart-wrap" v-if="cartLists_count>0 && !confirmordershow">
<view class="cart-wrap" v-if="cartLists_count > 0 && !confirmordershow">
<view class="cart-content">
<view class="left">
<view class="iconBox">
@@ -294,6 +286,7 @@
</view>
</view>
</view>
<!-- 套餐 -->
<view v-else>
<view class="shop_sku_box">
<view class="shop_sku_box_name">
@@ -362,6 +355,7 @@
onLoad,
onReady,
onShow,
onHide,
onPageScroll
} from '@dcloudio/uni-app'
@@ -579,9 +573,7 @@
type: '',
product_id: '',
sku_id: '',
groupSnap: {
goods: []
}
groupSnap: {}
})
// 用于判断接口数据是否加载完成
const isDataLoaded = ref(false);
@@ -621,10 +613,11 @@
});
specifications.sku_id = result.id
specifications.product_id = result.productId
specifications.item = Object.assign({}, result, specifications.item);
// 添加多规格分组
specifications.item.result = result
if (result.isPauseSale == 0) {
canSubmit.value = true;
skuBtnText.value = '添加到购物车'
// skuBtnText.value = '添加到购物车'
}
} catch (error) {
canSubmit.value = false;
@@ -682,55 +675,78 @@
}
}
// 使用 find 方法查找购物车是否有匹配的数组
// 根据购物车的数据匹配选中的商品查找是否有匹配的数组
const matchingProduct = async (data) => {
return matchedProducts.value.find(product => {
if (data.type === 'single') {
return product.skuId == data.skuId && product.id == data.id
console.log(specifications, matchedProducts.value, selectedOptions.value, '11111')
return matchedProducts.value.find((product, index) => {
if (data.type == 'package') {
// 套餐
let result = [];
if (product.type == "package") {
JSON.parse(product.cartListinfo.pro_group_info).goods.forEach(item1 => {
selectedOptions.value.forEach(item2 => {
if (item1.proId === item2.proId && item1.skuId === item2
.skuId) {
result.push(item1);
}
});
});
}
return result.length > 0 ? result : false;
} else if (specifications.item.type == 'sku') {
// 多规格
return product.skuId == data.id && product.id == data.productId
} else {
return product.skuId == data.sku_id && product.id == data.product_id
// 其他
return product.skuId == data.skuId && product.id == data.id
}
});
}
// 提交选择并执行下一步操作的方法
const submitSelection = async () => {
if (!canSubmit.value) {
return false;
if (shopCartNumber.value > 0 && canSubmit.value) {
// 是否是套餐package
let res = await matchingProduct(specifications.item.type == "package" ? specifications.item :
specifications.item.result)
console.log(res)
if (res) {
await calculateValue(res.cartNumber, '+', shopCartNumber.value)
}
// 是否是套餐 有就传
if (specifications.item.type == "package") {
specifications.groupSnap.goods = selectedOptions.value
} else {
specifications.groupSnap = null
}
console.log(specifications.groupSnap, 'specifications.groupSnap.goods')
websocketsendMessage({
id: res ? res.cartListId : '',
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,
goods_type: specifications.item.type == "package" ? 'package' : ''
})
// 清空有无无清空套餐
showShopsku.value = 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: ''
@@ -739,21 +755,18 @@
// 初始化 多规格选中
selectedSpecs.value = {}
canSubmit.value = false
skuBtnText.value = '请选择规格'
// 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.product_id = res.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.type = res.type
specifications.item.selectSpecInfo = Object.fromEntries(
Object.entries(specifications.item.selectSpecInfo).filter(([_, value]) => value.length > 0)
);
@@ -764,11 +777,15 @@
// 单规格
const singleclick = async (item, i) => {
if (selectedOptions.value.length > 0) {
specifications.groupSnap.goods = selectedOptions.value
}
// 判断购物车是否有该选中商品
let res = await matchingProduct(item)
// 是否是套餐 有就传
console.log(specifications, '单规格')
if (specifications.item.type == "package") {
specifications.groupSnap.goods = selectedOptions.value
} else {
specifications.groupSnap = null
}
websocketsendMessage({
id: res ? item.cartListId : '',
type: 'shopping',
@@ -777,19 +794,21 @@
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,
number: await calculateValue(item.cartNumber, i)
// pro_group_info: specifications.groupSnap,
// goods_type: specifications.item.type == "package" ? 'package' : ''
// pro_group_info: specifications.groupSnap
})
}
// 封装加法函数
const calculateValue = (cartNumber, i, step = 1) => {
if (i == '+') {
const result = parseFloat(cartNumber) + step;
const result = parseFloat(cartNumber) + parseFloat(step);
return result.toFixed(2);
} else {
// 当减到0返回del
const result = parseFloat(cartNumber) - step;
const result = parseFloat(cartNumber) - parseFloat(step);
return result == 0 ? 'del' : result.toFixed(2);
}
}
@@ -808,7 +827,10 @@
isConnected,
sendMessage,
closeSocket: manualClose,
receivedMessages
receivedMessages,
closeExistingConnection,
onShowconnect,
initNetworkListener
} = useWebSocket(options);
@@ -823,68 +845,70 @@
// 更新商品数量的方法
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
}
});
});
// 先将所有商品的 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.hots.forEach((group) => {
// 商品 id 匹配
if (group.id == cartItem.product_id) {
// 更新商品的数量
group.cartListId = cartItem.id
group.cartNumber = cartItem.number
});
// 再去更新数组的值
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
}
});
});
} else {
shopProductList.hots.forEach((i) => {
i.cartNumber = 0
})
});
// 遍历购物车数组
cartListFilter.value.forEach((cartItem) => {
// 遍历商品列表二维数组
shopProductList.productInfo.forEach((group) => {
group.productList.forEach((product) => {
product.cartNumber = 0
});
shopProductList.hots.forEach((group) => {
// 商品 id 匹配
if (group.id == cartItem.product_id) {
// 更新商品的数量
group.cartListId = cartItem.id
group.cartNumber = cartItem.number
}
});
}
});
}
//websocket产值
const websocketsendMessage = (data) => {
sendMessage(data)
uni.$u.debounce(sendMessage(data), 500)
}
// 用于记录已经处理过的消息的 msg_id
const processedMessageIds = new Set();
// 监听接收到的消息变化
watchEffect(async () => {
if (isDataLoaded.value && receivedMessages.value.length > 0) {
const Message = receivedMessages.value[receivedMessages.value.length - 1];
if (isDataLoaded.value && receivedMessages.value) {
const Message = receivedMessages.value
if (Message) {
// 心跳返回 过滤
if (Message.type == "ping_interval" || Message.msg_id == "ping_interval") {
return false
}
// 初始化
if (Message.operate_type == "shopping_init") {
cartList.value = Message.data
}
// 购物车数据更新从新请求
if (Message.type == 'product') {
isDataLoaded.value = false;
uni.$u.debounce(productqueryProduct(), 500)
// 数据可以更新
// 清空购物车
if (Message.operate_type == 'shopping_cleanup') {
cartList.value = []
showCart.value = false
}
// 初始化购物车数据
@@ -893,8 +917,8 @@
}
// 删除除购物车
if (Message.operate_type == 'shopping_del') {
cartList.value = cartList.value.filter(item => item.id !== Message.data.id);
if (Message.operate_type == 'shopping_del' && Message.status == 1) {
cartList.value = cartList.value.filter(item => item.id != Message.data.id);
}
// 添加或者减少购物后返回
@@ -910,10 +934,11 @@
});
}
// 清空购物车
if (Message.operate_type == 'shopping_cleanup') {
// 购物车数据更新从新请求
if (Message.type == 'product') {
cartList.value = []
showCart.value = false
isDataLoaded.value = false;
productqueryProduct()
}
//除去p 每次返回都回执消息
@@ -922,11 +947,11 @@
msg_id: Message.msg_id
})
// if(Message.status != 1){
// uni.showToast({
// title:'操作失败请稍后重试~'
// })
// }
// 检查消息是否已经处理过
if (processedMessageIds.has(Message.msg_id)) {
return;
}
processedMessageIds.add(Message.msg_id);
// 初始化商品数量
await updateProductQuantities()
@@ -937,78 +962,78 @@
// 更新购物车数据shopProductList.hots
const matchedProducts = computed(() => {
if (!cartList.value) {
return false;
}
let Specialstop = null
if (cartList.value.length > 0) {
let Specialstop = null
try {
Specialstop = [...[{
id: "",
name: "",
productList: shopProductList.hots
}], ...shopProductList.productInfo]
} catch (error) {
Specialstop = shopProductList.productInfo
//TODO handle the exception
}
return cartList.value.map((cartItem) => {
for (const group of Specialstop) {
for (const product of group.productList) {
if (product.id == cartItem.product_id) {
return {
...product,
cartListinfo: cartItem,
cartListId: cartItem.id, //购物车id
cartNumber: cartItem.number //增加一个数量算法
// cartNumberToAdd: cartItem.number //增加一个数量算法
};
try {
Specialstop = [...[{
id: "",
name: "",
productList: shopProductList.hots
}], ...shopProductList.productInfo]
} catch (error) {
Specialstop = shopProductList.productInfo
//TODO handle the exception
}
return cartList.value.map((cartItem) => {
for (const group of Specialstop) {
for (const product of group.productList) {
if (product.id == cartItem.product_id) {
// 多规格
if (product.type == 'sku') {
product.skuList.forEach((item) => {
if (item.id == product.id && item.productId == product.id) {
product.salePrice = item.salePrice
product.memberPrice = item.memberPrice
product.originPrice = item.originPrice
}
})
}
// 单规格
return {
...product,
// cartListinfo:cartItem
cartListId: cartItem.id,
// cartNumberToAdd: product.type == 'weight' ? 1 : cartItem.number //增加一个数量算法
cartNumberToAdd: cartItem.number //增加一个数量算法
};
}
}
}
// 如果没找到匹配的商品,返回 null 或者其他默认值,这里返回 null
return null;
}).filter(item => item !== null);
// 如果没找到匹配的商品,返回 null 或者其他默认值,这里返回 null
return null;
}).filter(item => item !== null);
} else {
return []
}
})
// 计算购物车商品总数量
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);
if (matchedProducts.value.length > 0) {
return matchedProducts.value.reduce((sum, item) => {
// 将 cartNumberToAdd 转换为数字
// const num = typeof item.cartNumberToAdd === 'string' ? parseFloat(item.cartNumberToAdd) : item.cartNumberToAdd;
const num = typeof item.cartNumber === 'string' ? parseFloat(item.cartNumber) : item
.cartNumber;
return sum + num;
}, 0);
} else {
return 0;
}
});
// 计算购物车商品总价格
const totalPrices = computed(() => {
// 购物车总数价格
let cart = matchedProducts.value.reduce((total, item) => {
// 是否启用会员价 0否1是
if (shopInfo.isVip == 1 && shopInfo.isMemberPrice == 1) {
// memberPrice会员价
return total + parseFloat(item.memberPrice) * parseFloat(item.cartNumber);
} else {
// salePrice销售价
return total + parseFloat(item.salePrice) * parseFloat(item.cartNumber);
}
}, 0);
// 向上取整并保留两位小数
return cart = Math.ceil(cart * 100) / 100;
if (matchedProducts.value.length > 0) {
// 购物车总数价格
let cart = matchedProducts.value.reduce((total, item) => {
// 是否启用会员价 0否1是
if (shopInfo.isVip == 1 && shopInfo.isMemberPrice == 1) {
// memberPrice会员价
return total + parseFloat(item.memberPrice) * parseFloat(item.cartNumber);
} else {
// salePrice销售价
return total + parseFloat(item.salePrice) * parseFloat(item.cartNumber);
}
}, 0);
// 向上取整并保留两位小数
return cart = Math.ceil(cart * 100) / 100;
} else {
return 0
}
});
// 储存是否存在多次下单
@@ -1085,30 +1110,44 @@
try {
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()
// 数据可以更新
isDataLoaded.value = true;
} catch (error) {
} catch (error) {}
// 如果商品报错就返回上一页
if (!shopProductList.productInfo || !shopProductList.hots) {
uni.navigateBack()
//TODO handle the exception
return false;
}
//TODO handle the exception
//第一步:将所有商品的 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()
// 数据可以更新
isDataLoaded.value = true;
}
onLoad(async (e) => {
await proxy.$onLaunched;
})
onShow(() => {
// 监听页面显示和隐藏
onShowconnect()
})
onHide(() => {
closeExistingConnection()
})
onMounted(async () => {
await proxy.$onLaunched;
// 获取当前页面栈
@@ -1133,6 +1172,8 @@
await productqueryProduct()
setTimeout(() => {
// 启动网络监听
initNetworkListener()
getElementTop()
}, 500)
})