import { defineStore } from 'pinia'; import { ref, computed, reactive, watchEffect } from 'vue'; import { productminiApphotsquery, APIgroupquery, } from "@/common/api/product/product.js"; export const useCartsStore = defineStore('cart', () => { // const dinersNum = uni.cache.get('dinersNum') // const isVip = uni.cache.get('orderVIP').isVip //此用户是否是会员 // const isMemberPrice = uni.cache.get('ordershopUserInfo').isMemberPrice //此店是否可以用会员 // const isTableFee = uni.cache.get('ordershopUserInfo').isTableFee //此店是否免桌位费 // const tableFee = uni.cache.get('ordershopUserInfo').tableFee //一个餐位费多钱 const goodsIsloading = ref(true); //商品数据Map const goodsMap = reactive({}) //获取商品数据 async function goodsInit() { goodsIsloading.value=true; //获取招牌菜商品 const hotres = await productminiApphotsquery(); for (let product of hotres) { setGoodsMap(product.id, product) } //获取分组商品 const groupres = await APIgroupquery() for (let group of groupres) { for (let product of group.productList) { setGoodsMap(product.id, product) } } goodsIsloading.value = false } function setGoodsMap(product_id, data) { goodsMap[product_id] = data; } //websocket回执 const websocketsendMessage = (data) => { uni.$u.debounce(sendMessage(data), 500) } const isLoading = ref(true); function getProductDetails(v) { const goods = goodsMap[v.product_id] if (!goods) { return undefined } let skuData = undefined; skuData = goods?.skuList.find((sku) => sku.id == v.sku_id); // if (goods.type == 'package') { // //套餐商品 // const SnapSku = findInGroupSnapSku(goods.groupSnap, v.sku_id) // skuData = { ...SnapSku, salePrice: SnapSku ? SnapSku.price : 0 } // } else { // skuData = goods?.skuList.find((sku: { id: string, salePrice: number }) => sku.id == v.sku_id); // } skuData = goods?.skuList.find((sku) => sku.id == v.sku_id); if (skuData) { return { ...v, productId: v.product_id, salePrice: skuData ? skuData.salePrice : 0, price: skuData ? skuData.salePrice : 0, memberPrice: skuData ? skuData.memberPrice : 0, coverImg: goods.coverImg, productImg: goods.coverImg, name: goods.name, productName: goods.name, specInfo: skuData.specInfo, packFee: goods.packFee || 0, type: goods.type, skuData, skuName: skuData.name, num: v.number * 1 } } else { return undefined } } // 用于记录已经处理过的消息的 msg_id const processedMessageIds = new Set(); //购物车商品信息补全初始化 function cartsGoodsInfoInit(arr) { carts.value = arr.map(v => { return getProductDetails(v) }).filter(v => v) } //收到socket消息时对购物车进行处理 async function onMessage(Message) { console.log('Message'); console.log(Message); if (Message) { // 心跳返回 过滤 if (Message.type == "ping_interval" || Message.msg_id == "ping_interval") { isLoading.value = false; return false } // 检查消息是否已经处理过 if (processedMessageIds.has(Message.msg_id)) { return; } processedMessageIds.add(Message.msg_id); const msgData = Message.data // 初始化 if (Message.operate_type == "init") { console.log('carts init', msgData); cartsGoodsInfoInit(msgData) uni.hideLoading(); isLoading.value = false; } // 清空购物车 if (Message.operate_type == 'cleanup') { carts.value = [] } // 删除除购物车 if (Message.operate_type == 'del' && Message.status == 1) { // 优化:使用可选链操作符避免报错 carts.value = carts.value.filter(item => item.id !== msgData?.id); // carts.value = carts.value.filter(item => item.id != Message.data.id); } // 添加或者减少购物后返回 if (Message.operate_type == 'add' || Message.operate_type == 'edit') { const index = carts.value.findIndex((v => v.id == msgData.id)) if (index !== -1) { carts.value[index] = getProductDetails(msgData); } else { carts.value.push(getProductDetails(msgData)); } } // 历史订单 if (Message.operate_type == 'clearOrder') {} // 购物车数据更新从新请求 if (Message.type == 'product' && Message.data_type == 'product_update' && Message .operate_type == 'product_update') { await goodsInit() await cartsGoodsInfoInit() } // 提示 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: async (data) => { } }); } } } //购物车数据 const carts = ref([]) //历史订单数据 const oldOrder = ref({ detailMap: {}, originAmount: 0 }) // 会员信息 const orderVIP = ref(uni.cache.get('orderVIP') || { isVip: false }) function updateData(key, newval) { if (key === 'orderVIP') { uni.cache.set('orderVIP', newval) return orderVIP.value = newval } if (key === 'shopInfo') { uni.cache.set('shopInfo', newval) return shopInfo.value = newval } } // 商品订单会员 const shopInfo = ref(uni.cache.get('shopInfo') || { isMemberPrice: 0 }) //是否使用会员价 const useVipPrice = computed(() => { const isUse=(orderVIP.value.isVip && shopInfo.value.isMemberPrice)?true:false console.log('useVipPrice',isUse); return isUse }) function currentCalcMpneyNumber(item){ const n=item.number-(item.returnNum||0) return n<=0?0:n } //历史订单商品价格总和 const oldOrderMoney = computed(() => { let total = 0 for (let i in oldOrder.value.detailMap) { total += oldOrder.value.detailMap[i].reduce((prve, cur) => { if (cur.isGift) { return prve + 0 } const discount_sale_amount = cur.discount_sale_amount * 1 || 0 const memberPrice = cur.skuData ? (cur.skuData.memberPrice || cur.skuData .salePrice) : 0 const price = (discount_sale_amount || cur.salePrice || 0) const number =currentCalcMpneyNumber(cur) return prve + (number <= 0 ? 0 : number) * (discount_sale_amount || (useVipPrice .value ? memberPrice : price)) }, 0) } return total }) //当前购物车总价格 const totalPrice = computed(() => { const money = carts.value.reduce((prve, cur) => { const memberPrice = cur.memberPrice || cur.salePrice const price = useVipPrice.value ? memberPrice : cur.salePrice; const curMoney = price * currentCalcMpneyNumber(cur) return prve + curMoney }, 0) return money }) // 霸王餐购物车原价,不享受任何优惠 const totalOriginPrice = computed(() => { const money = carts.value.reduce((prve, cur) => { const curMoney = cur.salePrice * currentCalcMpneyNumber(cur) return prve + curMoney }, 0) return money }) //商品券抵扣金额 // const productCouponDiscountAmount = computed(() => { // let index = -1; // return quansSelArr.value.reduce((pre, cur) => { // index++; // return pre + returnProDiscount(cur, index) * 1; // }, 0); // }); //返回打包数量(称重商品打包数量最大为1) function returnCartPackNumber(cur) { const maxReturnNum = cur.number - (cur.returnNum || 0); let pack_number = cur.number; pack_number = (cur.product_type == 'weight' && pack_number > 1) ? 1 : pack_number; pack_number = Math.min(maxReturnNum, pack_number); pack_number = pack_number <= 0 ? 0 : pack_number return pack_number * 1 } //当前购物车打包费 const totalPackFee = computed(() => { const money = carts.value.reduce((prve, cur) => { const curMoney = (cur.packFee || 0) * currentCalcMpneyNumber(cur) return prve + curMoney }, 0) return money }) //打包费 const packFee = computed(() => { const nowPackFee = carts.value.reduce((acc, cur) => { return acc + (cur.packFee || 0) * returnCartPackNumber(cur) }, 0) let oldPackfee = 0; for (let i in oldOrder.value.detailMap) { oldPackfee += oldOrder.value.detailMap[i].reduce((prve, cur) => { return prve + (cur.packFee || 0) * returnCartPackNumber(cur) }, 0) } return nowPackFee + oldPackfee }) //购物车是否为空 const isEmpty = computed(() => { return !carts.value || carts.value.length <= 0 }) // 计算向上取整 const roundUpToTwoDecimals = (num, i) => { // 先将数字乘以 100 并转换为字符串保留足够的小数位 let temp = (num * 100).toFixed(10); // 向上取整 let rounded = null if (i == 'upward') { rounded = Math.ceil(parseFloat(temp)); } else { rounded = Math.floor(parseFloat(temp)); } // 再除以 100 得到保留两位小数的结果 return rounded / 100; }; // 精确计算函数 const preciseCalculation = (num1, num2) => { // 将数字转换为整数,乘以 100 以保留两位小数 const int1 = BigInt(Math.round(num1 * 100)); const int2 = BigInt(Math.round(num2 * 100)); // 执行乘法运算 const result = int1 * int2; // 再除以 10000 以还原为原来的小数 return Number(result) / 10000; }; // 计算购物车商品总价格 const getTotalTotalPrices = (matchedProducts, isBwc = true) => { if (!matchedProducts || !Array.isArray(matchedProducts)) { return 0; } // console.log(uni.cache.get('orderVIP').isVip, uni.cache.get('ordershopUserInfo').isMemberPrice, // 111) // 购物车总数价格 console.log('isBwc'); console.log(isBwc); let cart = matchedProducts.reduce((total, item) => { if(isBwc===true){ return total + (parseFloat(item.price) * parseFloat(item.num - item.returnNum)); } // 是否启用会员价 0否1是 if (useVipPrice.value) { // memberPrice会员价 return total + (parseFloat(item.memberPrice || item.price) * parseFloat(item .num - item .returnNum)); } else { // salePrice销售价 return total + (parseFloat(item.price) * parseFloat(item.num - item.returnNum)); } }, 0); cart = cart.toFixed(2) console.log(parseFloat(cart)) // 向上取整并保留两位小数 // let result = roundUpToTwoDecimals(cart, 'upward') return parseFloat(cart); }; // 计算商品卷所选择的总价格 const getTotalProductroll = (matchedProducts) => computed(() => { if (!matchedProducts || !Array.isArray(matchedProducts)) { return 0; } // 购物车总数价格 let cart = matchedProducts.reduce((total, item) => { // 是否启用会员价 0否1是 if (useVipPrice.value) { // memberPrice会员价 return total + parseFloat(item.memberPrice || item.price) } else { // salePrice销售价 return total + parseFloat(item.price) } }, 0); // 向上取整并保留两位小数 let result = roundUpToTwoDecimals(cart, 'upward') return result; }); // 桌位置 const getTotalSeatcharge = (seatNum) => computed(() => { // 是否免除桌位费 0 否 1 是 let cart = 0 if (uni.cache.get('ordershopUserInfo').isTableFee == 0 && seatNum) { cart = parseFloat(seatNum) * parseFloat(uni.cache.get('ordershopUserInfo').tableFee) // Math.ceil(parseFloat(seatNum) * parseFloat( // uni.cache.get('ordershopUserInfo').tableFee) * 100) / 100; } // 向下取整并保留两位小数 let result = roundUpToTwoDecimals(cart, 'downward') return result; }); // 计算购物车总打包费用(向下取整并保留两位小数) const getTotalPackFee = (cartList) => computed(() => { const total = cartList.reduce((sum, item) => { return sum + (parseFloat(item.packAmount) * (parseFloat(item.packNumber) || ( parseFloat(item.num) - parseFloat(item.returnNum)))); }, 0); // 向下取整并保留两位小数 let result = roundUpToTwoDecimals(total, 'downward') return result; // return Math.floor(total * 100) / 100; }); //获取热门商品 async function getHotProduct() { } //获取分组商品 async function getGroupProduct() { } return { getTotalPackFee, getTotalSeatcharge, getTotalTotalPrices, getTotalProductroll, carts, isEmpty, setGoodsMap, goodsIsloading, goodsInit, onMessage, totalPrice, totalPackFee, updateData, useVipPrice,totalOriginPrice }; } );