Files
cashier_wx/stores/carts.js

452 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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) {
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
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,
goodsMap,
goodsIsloading,
goodsInit,
onMessage,
totalPrice,
totalPackFee,
updateData,
useVipPrice,
totalOriginPrice
};
}
);