Files
cashier_wx/stores/carts.js

682 lines
19 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 yskUtils from 'ysk-utils'
// const {
// OrderPriceCalculator,
// BaseCartItem,
// BackendCoupon,
// ActivityConfig,
// OrderExtraConfig,
// MerchantReductionConfig,
// MerchantReductionType,
// GoodsType
// } = yskUtils
import yskUtils from 'ysk-utils'
const {OrderPriceCalculator}=yskUtils
import { ref, computed, reactive, watchEffect, watch } from "vue";
import {
productminiApphotsquery,
APIgroupquery,
} from "@/common/api/product/product.js";
export const useCartsStore = defineStore("cart", () => {
// 店铺信息
const shopInfo = ref(
uni.cache.get("shopInfo") || {
isMemberPrice: 0,
isTableFee: 1,
}
);
//用户信息
const shopUserInfo = ref(uni.cache.get("shopUserInfo") || {});
const consumeDiscount = ref({});
// 适配工具库 BaseCartItem 接口的商品数据转换函数
const convertToBaseCartItem = (item) => {
const skuData = item.skuData
? {
id: item.skuData.id || item.sku_id,
salePrice: item.skuData.salePrice || 0,
memberPrice: item.skuData.memberPrice || 0,
}
: undefined;
const goods = getProductDetails({
...item,
product_id: item.product_id || item.productId,
sku_id: item.skuId || item.sku_id,
});
console.log('convertToBaseCartItem',item)
const discountSaleAmount=item.discount_sale_amount?(item.discount_sale_amount*1) : (item.discountSaleAmount?item.discountSaleAmount*1:0)
return {
...item,
id: item.id,
sku_id: item.skuId || item.sku_id,
product_id: item.product_id || item.productId,
salePrice: item.salePrice || item.price,
number: item.number || item.num || 0,
product_type: item.productType,
is_temporary: !!(item.is_temporary || item.isTemporary),
is_gift: !!(item.is_gift || item.isGift),
is_time_discount: item.is_time_discount || item.isTimeDiscount ,
returnNum: item.returnNum || 0,
memberPrice: item.memberPrice || 0,
discountSaleAmount:discountSaleAmount,
packFee: item.packFee || (goods ? goods.packFee : 0) || 0,
packNumber: item.pack_number || item.packNumber || 0,
activityInfo: item.activityInfo
? {
type: item.activityInfo.type,
discountRate: OrderPriceCalculator.formatDiscountRate(
item.activityInfo.discountRate
),
vipPriceShare: !!item.activityInfo.vipPriceShare,
}
: undefined,
skuData,
};
};
// 合并所有商品列表
const allGoods = ref([]);
function getAllGoodsList() {
const currentGoods = carts.value.map(convertToBaseCartItem);
const giftGoods = [].map(convertToBaseCartItem);
// 扁平化历史订单商品
const oldOrderGoods = Object.values(oldOrder.value.detailMap || {})
.flat()
.map(convertToBaseCartItem);
console.log('oldOrder.value',oldOrder.value)
if(!oldOrder.value.id){
}
return [...currentGoods, ...giftGoods, ...oldOrderGoods];
}
// 就餐类型 'dine-in' | 'take-out'
let dinnerType = ref("dine-in");
function setDinnerType(str) {
dinnerType.value = str;
}
//餐位费配置
const dinersNum = uni.cache.get("dinersNum") || 0;
const seatFeeConfig = ref({
pricePerPerson: shopInfo.value.tableFee || 0,
personCount: dinersNum || 0,
isEnabled: !shopInfo.value.isTableFee,
});
watch(
() => shopInfo.value.isTableFee,
(newval) => {
seatFeeConfig.value.isEnabled = !shopInfo.value.isTableFee;
seatFeeConfig.value.pricePerPerson = shopInfo.value.tableFee || 0;
},
{
deep: true,
}
);
function setSeatFeeConfig(key, val) {
seatFeeConfig.value[key] = val;
}
watch(
() => seatFeeConfig.value,
(newval) => {
console.log("seatFeeConfig", seatFeeConfig.value);
},
{
deep: true,
}
);
//积分规则
const pointDeductionRule = ref({
pointsPerYuan: 0,
maxDeductionAmount: Infinity,
});
function setPointDeductionRule(pointsPerYuan, maxDeductionAmount) {
pointDeductionRule.value.pointsPerYuan = pointsPerYuan;
pointDeductionRule.value.maxDeductionAmount = maxDeductionAmount;
}
// 初始配置:默认无减免(固定金额 0 元)
const merchantReductionConfig = ref({
type: "fixed_amount",
fixedAmount: 0,
});
//使用积分数量
const userPoints = ref(0);
function setUserPoints(newval) {
userPoints.value = newval;
}
//新客立减
const newUserDiscount = ref(0);
//满减活动
const fullReductionActivities = ref([]);
//是否使用霸王餐
const isFreeDine = ref(false);
// 商家霸王餐配置
const freeDineConfig = ref(null);
//限时折扣
const limitTimeDiscount = ref(null);
// 订单额外配置
const orderExtraConfig = computed(() => ({
// 引用扩展后的商家减免配置
merchantReduction: merchantReductionConfig.value,
additionalFee: 0,
pointDeductionRule: pointDeductionRule.value,
seatFeeConfig: seatFeeConfig.value,
currentStoreId: "",
userPoints: userPoints.value,
isMember: useVipPrice.value,
memberDiscountRate: 1,
newUserDiscount: newUserDiscount.value,
fullReductionActivities: fullReductionActivities.value,
currentDinnerType: dinnerType.value,
isFreeDine: isFreeDine.value,
freeDineConfig: freeDineConfig.value,
limitTimeDiscount: limitTimeDiscount.value,
shopUserInfo: shopUserInfo.value,
}));
// 营销活动列表
const activityList = computed(() => {
return [];
});
// 优惠券列表
const backendCoupons = ref([]);
function setCoupons(cps) {
console.log("setCoupons", cps);
backendCoupons.value = cps;
}
// 商品加入购物车顺序
const cartOrder = ref({});
// 订单费用汇总
const orderCostSummary = computed(() => {
allGoods.value = getAllGoodsList();
console.log("allGoods.value", allGoods.value);
console.log("orderExtraConfig.value", orderExtraConfig.value);
const costSummary = OrderPriceCalculator.calculateOrderCostSummary(
allGoods.value,
dinnerType.value,
backendCoupons.value,
activityList.value,
orderExtraConfig.value,
cartOrder.value,
new Date()
);
console.log(" 订单费用汇总", costSummary);
return costSummary;
});
const goodsIsloading = ref(true);
//商品数据Map
const goodsMap = reactive({});
function returnGoods(product_id) {
return goodsMap[product_id * 1];
}
//获取商品数据
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);
}
}
allGoods.value = getAllGoodsList();
goodsIsloading.value = false;
}
function setGoodsMap(product_id, data) {
goodsMap[product_id] = data;
}
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 (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) {
console.log('cartsGoodsInfoInit',arr)
if(arr&&Array.isArray(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 Message", Message);
console.log("carts init", msgData);
if(!oldOrder.value.id){
limitTimeDiscount.value = Message.time_dis_info;
}
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);
}
// 添加或者减少购物后返回
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.operate_type == "time_discount_get"){
console.log("time_discount_get", Message.data);
limitTimeDiscount.value = Message.data;
}
if(Message.operate_type == "time_discount_save"){
console.log("time_discount_save", Message.data);
limitTimeDiscount.value = Message.data;
}
if (Message.type == "no_suit_num") {
uni.showModal({
title: "提示",
showCancel: false,
content: "此商品库存不足起售数量!",
success: async (data) => {},
});
}
}
}
//购物车数据
const carts = ref([]);
//历史订单数据
const oldOrder = ref({
detailMap: {},
originAmount: 0,
});
function setOldOrder(data) {
console.log("setOldOrder", data);
oldOrder.value = data;
allGoods.value = getAllGoodsList();
}
// 会员信息
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 useVipPrice = computed(() => {
if (!shopUserInfo.value) {
return false;
}
const isUse =
shopUserInfo.value.isVip && shopUserInfo.value.isMemberPrice && shopInfo.value.isMemberPrice==1
? true
: false;
return isUse;
});
function currentCalcMpneyNumber(item) {
const n = item.number - (item.returnNum || 0);
return n <= 0 ? 0 : n;
}
//当前购物车总价格
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;
});
//返回打包数量称重商品打包数量最大为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;
}
// 购物车总数价格
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);
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);
}
// 向下取整并保留两位小数
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;
});
function clearOrderConfig() {
console.log("clearOrderConfig");
backendCoupons.value = [];
allGoods.value = [];
carts.value = [];
seatFeeConfig.value.personCount = uni.cache.get("dinersNum") || 0;
dinnerType.value = "dine-in";
userPoints.value = 0;
fullReductionActivities.value = [];
isFreeDine.value = false;
oldOrder.value = {
detailMap: {},
originAmount: 0,
};
}
return {
getTotalPackFee,
getTotalSeatcharge,
getTotalTotalPrices,
getTotalProductroll,
carts,
isEmpty,
setGoodsMap,
goodsMap: goodsMap,
goodsIsloading,
goodsInit,
onMessage,
totalPrice,
totalPackFee,
updateData,
useVipPrice,
totalOriginPrice,
orderCostSummary,
setCoupons,
userPoints,
setUserPoints,
setPointDeductionRule,
setOldOrder,
//返回商品信息
returnGoods,
//优惠券列表
backendCoupons,
allGoods,
//就餐类型
dinnerType,
setDinnerType,
setSeatFeeConfig,
seatFeeConfig,
shopInfo,
//新客立减数据
consumeDiscount,
//新客立减金额
newUserDiscount,
getAllGoodsList,
//清空配置
clearOrderConfig,
//满减活动
fullReductionActivities,
isFreeDine, //是否使用霸王餐
// 商家霸王餐配置
freeDineConfig,
//限时折扣
limitTimeDiscount,
shopUserInfo,
};
});