Files
cashier-web/src/store/modules/carts.ts
2025-03-07 18:53:31 +08:00

613 lines
19 KiB
TypeScript
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 { store } from "@/store";
import WebSocketManager, { type ApifoxModel, msgType } from "@/utils/websocket";
import orderApi from "@/api/order/order";
import { useUserStoreHook } from "@/store/modules/user";
const shopUser = useUserStoreHook();
export interface CartsState {
id: string | number;
[property: string]: any;
}
export const useCartsStore = defineStore("carts", () => {
//选择用户
const vipUser = ref<{ id?: string | number, isVip?: boolean }>({});
function changeUser(user: any) {
vipUser.value = user;
}
//是否启用会员价
const useVipPrice = computed(() => {
return (shopUser.userInfo.isMemberPrice && vipUser.value.id && vipUser.value.isVip) ? true : false
})
//台桌id
const table_code = ref('');
//购物车是否初始化连接加载完成
const isLinkFinshed = ref(false)
//当前购物车数据
const list = useStorage<any[]>("carts", []);
//历史订单数据
const oldOrder = useStorage<any>("Instead_olold_order", {
detailMap: [],
originAmount: 0
});
//代客下单页面商品缓存
const goods = useStorage<any[]>("Instead_goods", []);
//赠菜
const giftList = useStorage<any[]>("giftList", []);
let goodsMap: { [key: string]: any } = useStorage('Instead_goods_map', {});
//当前选中cart
let selListIndex = ref(-1);
//当前选中商品是否是赠菜
const isSelGift = ref(false);
//当前选中是否是历史订单
const isOldOrder = ref(false);
//选中历史订单中的第几次下单
const selPlaceNum = ref(-1);
const defaultCart = {
id: '',
number: 0,
}
//购物车是否为空
const isEmpty = computed(() => {
return list.value.length === 0 && giftList.value.length === 0
})
//当前购物车选中数据
const selCart = computed(() => {
if (isOldOrder.value && selPlaceNum.value >= 0) {
return oldOrder.value.detailMap[selPlaceNum.value][selListIndex.value]
}
if (isSelGift.value) {
return giftList.value[selListIndex.value] || defaultCart
}
return list.value[selListIndex.value] || defaultCart
})
//当前购物车选中对应商品数据
const selGoods = computed(() => {
return goodsMap[selCart.value.product_id]
})
//当前选中购物车数据是否是可选套餐商品
const isCanSelectGroup = computed(() => {
if (!selGoods.value) {
return false
}
return selGoods.value.type == 'package' && selGoods.value.groupType == 1
})
//赠菜总价
const giftMoney = computed(() => {
let oldGiftMoney = 0
for (let i in oldOrder.value.detailMap) {
oldGiftMoney += oldOrder.value.detailMap[i].reduce((prve: number, cur: any) => {
return prve + cur.number * cur.salePrice
}, 0)
}
return giftList.value.reduce((acc: number, cur: any) => {
return acc + cur.number * cur.salePrice
}, 0)
})
//打包数量
const packNum = computed(() => {
const nowCartNumber = list.value.reduce((acc: number, cur: any) => {
return acc + cur.pack_number * 1
}, 0)
const giftNumber = giftList.value.reduce((acc: number, cur: any) => {
return acc + cur.pack_number * 1
}, 0)
let oldNumber = 0
for (let i in oldOrder.value.detailMap) {
oldNumber += oldOrder.value.detailMap[i].reduce((prve: number, cur: any) => {
return prve + cur.pack_number
}, 0)
}
return nowCartNumber + giftNumber + oldNumber
})
//打包费
const packFee = computed(() => {
const nowPackFee = list.value.reduce((acc: number, cur: any) => {
return acc + (cur.packFee || 0) * cur.pack_number
}, 0)
const giftPackFee = giftList.value.reduce((acc: number, cur: any) => {
return acc + (cur.packFee || 0) * cur.pack_number
}, 0)
let oldPackfee = 0;
for (let i in oldOrder.value.detailMap) {
oldPackfee += oldOrder.value.detailMap[i].reduce((prve: number, cur: any) => {
return prve + (cur.packFee || 0) * cur.pack_number
}, 0)
}
return nowPackFee + giftPackFee + oldPackfee
})
//会员优惠
const vipDiscount = computed(() => {
if (!useVipPrice.value) {
return 0
}
const listTotal = list.value.reduce((acc: number, cur: any) => {
const n = (cur.salePrice * 1 - cur.memberPrice * 1) * cur.number
return acc + (n <= 0 ? 0 : n)
}, 0)
return listTotal
})
//单品改价优惠
const singleDiscount = computed(() => {
const listTotal = list.value.reduce((acc: number, cur: any) => {
if (cur.discount_sale_amount * 1 <= 0) {
return acc + 0
}
const originPrice = useVipPrice.value ? (cur.memberPrice || cur.salePrice) : cur.salePrice
const n = (originPrice * 1 - cur.discount_sale_amount * 1) * cur.number
return acc + (n <= 0 ? 0 : n)
}, 0)
return listTotal
})
// 优惠
const yiyouhui = computed(() => {
const youhui = giftMoney.value * 1 + vipDiscount.value * 1 + singleDiscount.value * 1
if (youhui > 0) {
return '已优惠¥' + youhui.toFixed(2)
}
return ''
})
//历史订单价格
const oldOrderMoney = computed(() => {
let total = 0
for (let i in oldOrder.value.detailMap) {
console.log(oldOrder.value)
total += oldOrder.value.detailMap[i].reduce((prve: number, cur: any) => {
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 = (cur.number - cur.returnNum)
return prve + (number <= 0 ? 0 : number) * (discount_sale_amount || (useVipPrice.value ? memberPrice : price))
}, 0)
}
return total
})
//支付总价
const payMoney = computed(() => {
const money = list.value.reduce((acc: number, cur: any) => {
const discount_sale_amount = cur.discount_sale_amount * 1 || 0
const memberPrice = cur.skuData ? (cur.skuData.memberPrice || cur.skuData.salePrice) : 0
const price = (cur.discount_sale_amount * 1 || cur.salePrice || 0)
return acc + cur.number * (discount_sale_amount || (useVipPrice.value ? memberPrice : price))
}, 0)
return (money + packFee.value + oldOrderMoney.value * 1).toFixed(2)
})
//只算商品的总价
const goodsTotal = computed(() => {
const money = list.value.reduce((acc: number, cur: any) => {
const discount_sale_amount = cur.discount_sale_amount * 1 || 0
const memberPrice = cur.skuData ? (cur.skuData.memberPrice || cur.skuData.salePrice) : 0
const price = (cur.discount_sale_amount * 1 || cur.salePrice || 0)
return acc + cur.number * (discount_sale_amount || (useVipPrice.value ? memberPrice : price))
}, 0)
return (money + oldOrderMoney.value * 1).toFixed(2)
})
//总计数量
const totalNumber = computed(() => {
const cartNumber = list.value.reduce((acc: number, cur: any) => {
return acc + cur.number * 1
}, 0)
const giftNumber = list.value.reduce((acc: number, cur: any) => {
return acc + cur.number * 1
}, 0)
let oldNumber = 0
for (let i in oldOrder.value.detailMap) {
oldNumber += oldOrder.value.detailMap[i].reduce((prve: number, cur: any) => {
return prve + cur.number * 1
}, 0)
}
return cartNumber + giftNumber + oldNumber
})
function changeNumber(step: number, item: CartsState) {
if (item.number * 1 + step <= 0) {
del(item);
return;
}
const newNumber = item.number * 1 + step * 1;
update({ ...item, number: item.number * 1 + step * 1, pack_number: newNumber < item.pack_number ? (item.pack_number * 1 + step * 1) : item.pack_number });
}
function changeSelCart(cart: CartsState) {
console.log(cart)
if (!cart.id) {
return
}
if (cart.placeNum) {
selPlaceNum.value = cart.placeNum
isOldOrder.value = true
console.log(oldOrder.value.detailMap[cart.placeNum])
selListIndex.value = oldOrder.value.detailMap[cart.placeNum].findIndex((item: CartsState) => {
return item.id == cart.id
})
return
}
if (cart.is_gift) {
isSelGift.value = true
} else {
isSelGift.value = false
}
if (cart.is_gift) {
isSelGift.value = true
selListIndex.value = giftList.value.findIndex((item: CartsState) => item.id === cart.id);
console.log(selListIndex.value)
} else {
isSelGift.value = false
selListIndex.value = list.value.findIndex((item: CartsState) => item.id === cart.id);
}
}
const basic_msg = {
number: 1,
is_gift: 0,
is_temporary: 0,
discount_sale_amount: 0,
discount_sale_note: "",
is_print: 1,
pro_group_info: '',
is_wait_call: 0,
product_name: "",
remark: "",
sku_id: '',
}
//当前购物车直接添加
function cartsPush(data: any) {
sendMessage('add', {
...basic_msg,
...data
});
}
function add(data: any) {
const msg = {
...basic_msg,
...data
}
const hasCart = list.value.find((cartItem) => {
return cartItem.product_id == msg.product_id && cartItem.sku_id == msg.sku_id;
});
if (hasCart) {
update({ ...hasCart, ...msg, number: hasCart.number * 1 + msg.number * 1 })
} else {
console.log(msg);
sendMessage('add', msg);
}
}
// 换桌
function changeTable(newVal: string | number) {
if (table_code.value) {
sendMessage('rottable', {
new_table_code: newVal,
table_code: table_code.value
});
} else {
table_code.value = `${newVal}`;
}
}
function del(data: any) {
sendMessage('del', data);
}
function update(data: any) {
console.log(data);
if (data.number * 1 < data.skuData.suitNum * 1) {
return sendMessage('del', data);
}
sendMessage('edit', data);
}
function updateTag(key: string, val: any, cart: CartsState = selCart.value) {
if (cart.number * 1 < cart.skuData.suitNum * 1) {
return sendMessage('del', cart);
}
console.log(key, val)
if (key == 'discount_sale_amount' && val * 1 <= 0) {
return ElMessage.error('价格不能为0')
}
sendMessage('edit', { ...cart, [key]: val });
}
function clear() {
sendMessage('cleanup', {});
}
function dataReset() {
selListIndex.value = -1;
selPlaceNum.value = 1
isOldOrder.value = false
isSelGift.value = false
list.value = [];
giftList.value = [];
oldOrder.value = {
detailMap: [],
originAmount: 0
}
vipUser.value = {}
}
// 寻找套餐商品sku
interface GroupSnap {
goods: { [key: string]: any }[];
}
function findInGroupSnapSku(groupSnap: GroupSnap[], sku_id: string | number) {
for (let i in groupSnap) {
const sku = groupSnap[i].goods.find(v => v.sku_id == sku_id)
if (sku) {
return sku
}
}
}
function getProductDetails(v: { product_id: string, sku_id: string }) {
const goods = goodsMap[v.product_id]
if (!goods) {
return undefined
}
let skuData = undefined;
skuData = goods?.skuList.find((sku: { id: string, salePrice: number }) => 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: { id: string, salePrice: number }) => sku.id == v.sku_id);
if (skuData) {
return {
salePrice: skuData ? skuData.salePrice : 0,
memberPrice: skuData ? skuData.memberPrice : 0,
coverImg: goods.coverImg,
name: goods.name,
specInfo: skuData.specInfo,
packFee: goods.packFee || 0,
type: goods.type,
skuData
}
} else {
return undefined
}
}
function returnDetailMap(data: any) {
const newData: { [key: string]: any } = {}
for (let i in data) {
newData[i] = data[i].map((v: any) => {
const skuData = getProductDetails({ product_id: v.productId, sku_id: v.skuId })
return {
...v,
...skuData,
placeNum: v.placeNum,
number: v.num,
id: v.id,
pack_number: v.packNumber,
discount_sale_amount: v.discountSaleAmount * 1 || 0
}
})
}
return newData
}
function setOldOrder(data: any) {
oldOrder.value = {
...data,
detailMap: returnDetailMap(data.detailMap)
}
}
/**
*
* @param initParams 购物车初始化参数
* @param $goodsMap 商品id对应的map
* @param oldOrder 历史订单数据
*/
function init(initParams: ApifoxModel, $goodsMap: any, $oldOrder: any) {
// 商品id对应的数据map
if ($goodsMap) {
goodsMap = $goodsMap
}
if ($oldOrder) {
setOldOrder($oldOrder)
}
// console.log('oldOrder.detailMap', oldOrder.value.detailMap)
// const cache_table_code = localStorage.getItem('cache_table_code');
// const randomTableCode = cache_table_code ? cache_table_code : ('APC' + (1000 + Math.floor(Math.random() * 9000)))
initParams.table_code = initParams.table_code ? initParams.table_code : ''
table_code.value = initParams.table_code
// localStorage.setItem('cache_table_code', table_code.value);
WebSocketManager.subscribeToTopic(initParams, (msg) => {
console.log("收到消息:", msg);
if (msg.hasOwnProperty('status') && msg.status != 1) {
return ElMessage.error(msg.message || '操作失败')
}
if (msg && msg.data) {
if (Array.isArray(msg.data) && msg.data.length) {
table_code.value = msg.data[0].table_code
}
if (msg.data.table_code) {
table_code.value = table_code.value ? table_code.value : msg.data.table_code
}
if (msg.table_code) {
table_code.value = table_code.value ? table_code.value : msg.table_code
}
}
// 初始化
if (msg.operate_type === "manage_init") {
isLinkFinshed.value = true
// 设置单价
list.value = msg.data.filter((v: Record<string, any>) => {
if (v.is_temporary) {
return v
}
const skuData = getProductDetails({ product_id: v.product_id, sku_id: v.sku_id })
if (skuData) {
(Object.keys(skuData) as (keyof typeof skuData)[]).forEach((key) => {
v[key] = skuData[key];
});
} else {
del({ id: v.id })
return false
}
return !v.is_gift
})
giftList.value = msg.data.filter((v: Record<string, any>) => {
if (v.is_temporary) {
return v && v.is_gift
}
const skuData = getProductDetails({ product_id: v.product_id, sku_id: v.sku_id })
if (skuData) {
(Object.keys(skuData) as (keyof typeof skuData)[]).forEach((key) => {
v[key] = skuData[key];
});
} else {
del({ id: v.id })
return false
}
return v.is_gift
})
}
//广播
if (msg.type === "bc") {
msg.operate_type = 'manage_' + msg.operate_type
}
if (msg.operate_type === "manage_add") {
if (list.value.find(v => v.id == msg.data.id)) {
return ElMessage.warning(msg.message || '该商品已存在')
}
const skuData = getProductDetails({ product_id: msg.data.product_id, sku_id: msg.data.sku_id })
list.value.push({ ...skuData, ...msg.data })
return ElMessage.success(msg.message || '添加成功')
}
if (msg.operate_type === "manage_edit") {
const newCart = msg.data
const index = list.value.findIndex((item) => item.id === newCart.id)
const giftIndex = giftList.value.findIndex((item) => item.id === newCart.id)
const cartItem = list.value[index] || { is_gift: false };
const giftItem = giftList.value[giftIndex];
if (isSelGift.value) {
//操作赠菜
if (newCart.is_gift != giftItem.is_gift) {
//修改了赠菜状态
giftList.value.splice(giftIndex, 1)
list.value.push({ ...giftItem, ...newCart })
selListIndex.value = -1
} else {
giftList.value[giftIndex] = { ...giftItem, ...newCart }
}
ElMessage.success(msg.message || '修改成功')
return
}
if (!isSelGift.value) {
//操作非赠菜
if (newCart.is_gift != cartItem.is_gift) {
list.value.splice(index, 1)
giftList.value.push({ ...cartItem, ...newCart })
selListIndex.value = -1
} else {
list.value[index] = { ...cartItem, ...newCart }
}
ElMessage.success(msg.message || '修改成功')
return
}
}
if (msg.operate_type === "manage_del") {
if (!isSelGift.value) {
const index = list.value.findIndex((item) => item.id === msg.data.id)
if (index > -1) {
list.value.splice(index, 1)
if (list.value.length >= 1) {
selListIndex.value = index - 1;
}
return ElMessage.success(msg.message || '删除成功')
}
} else {
const index = giftList.value.findIndex((item) => item.id === msg.data.id)
if (index > -1) {
giftList.value.splice(index, 1)
if (giftList.value.length >= 1) {
selListIndex.value = index - 1;
}
return ElMessage.success(msg.message || '删除成功')
}
}
}
if (msg.operate_type === "manage_cleanup") {
dataReset()
}
console.log(list.value)
});
}
const delArr = ['skuData', 'coverImg', 'specInfo', 'placeNum', 'update_time', 'create_time', 'packFee', 'memberPrice', 'type']
function sendMessage(operate_type: msgType, message: any) {
const msg = { ...message, operate_type: operate_type, table_code: table_code.value }
if (operate_type == 'edit') {
for (let i in delArr) {
delete msg[delArr[i]]
}
}
console.log('send msg', msg)
WebSocketManager.sendMessage(msg);
}
return {
goodsTotal,
isLinkFinshed,
setOldOrder,
singleDiscount,
vipDiscount,
dataReset,
useVipPrice,
changeUser,
packNum, packFee,
isOldOrder,
oldOrder,
isCanSelectGroup,
goods,
selGoods,
cartsPush,
table_code,
updateTag,
list,
add,
del,
update,
init,
changeNumber, isEmpty,
selCart, totalNumber,
changeSelCart, payMoney,
clear, yiyouhui, giftList,
changeTable
};
});
export function useCartsStoreHook() {
return useCartsStore(store);
}