From 13ad5a0de4f206728acddc58305737937bbc1904 Mon Sep 17 00:00:00 2001 From: YeMingfei666 <1619116647@qq.com> Date: Tue, 29 Apr 2025 10:33:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E5=AE=A2=E4=B8=8B=E5=8D=95=E9=87=8D?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.vue | 6 - common/js/carts-websocket.js | 360 --- common/js/carts-websocket.ts | 244 ++ common/js/{carts.js => carts.ts} | 0 pages/order/components/orderInfo.vue | 4 - pages/order/confirm-order.vue | 4 +- .../components/confirmorder - 副本.vue | 1406 +++++++++ pages/product/components/shoppingCartes.vue | 114 +- pages/product/index - 副本.vue | 2631 +++++++++++++++++ pages/product/index.vue | 703 +---- pages/test/test.vue | 68 +- stores/carts.js | 452 --- stores/carts.ts | 821 +++++ stores/user.js | 10 +- utils/product.js | 47 + 15 files changed, 5345 insertions(+), 1525 deletions(-) delete mode 100644 common/js/carts-websocket.js create mode 100644 common/js/carts-websocket.ts rename common/js/{carts.js => carts.ts} (100%) create mode 100644 pages/product/components/confirmorder - 副本.vue create mode 100644 pages/product/index - 副本.vue delete mode 100644 stores/carts.js create mode 100644 stores/carts.ts create mode 100644 utils/product.js diff --git a/App.vue b/App.vue index fdda864..e824611 100644 --- a/App.vue +++ b/App.vue @@ -1,7 +1,4 @@ + + \ No newline at end of file diff --git a/pages/product/components/shoppingCartes.vue b/pages/product/components/shoppingCartes.vue index 04c9986..6115b13 100644 --- a/pages/product/components/shoppingCartes.vue +++ b/pages/product/components/shoppingCartes.vue @@ -3,13 +3,6 @@ - @@ -29,15 +22,15 @@ - {{item.cartListinfo.is_temporary == 1?'临时菜' :item.name }} + {{item.is_temporary == 1?'临时菜' :item.name }} - - {{item.cartListinfo.sku_id == i.id? i.name:"" }} + + {{item.skuData.name||''}} - + {{i.proName }} @@ -47,15 +40,14 @@ - - - - - {{item.cartListinfo.sku_id == i.id?(shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(i.memberPrice || i.salePrice):i.salePrice):''}} + + + + {{item.memberPrice || item.salePrice}} - {{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(item.memberPrice || item.salePrice):item.salePrice}} + {{item.salePrice}} - + @@ -104,7 +96,7 @@ } from '@/stores/user.js'; // 定义自定义事件 - const emits = defineEmits(['customevent', 'close', 'clickcancelOrder']); + const emits = defineEmits(['changeNumber', 'close', 'clearCarts']); const props = defineProps({ cartList: { @@ -127,54 +119,16 @@ }); const shopInfo = uni.cache.get('shopInfo') - // 定义 ifcartNumber 计算属性方法 - const ifcartNumber = computed(() => { - return (item) => { - // 如果 item 为空或者 cartNumber 不是字符串类型,返回 0 - if (!item || typeof item.cartNumber !== 'string') { - return 0; - } - let numValue = parseFloat(item.cartNumber); - if (isNaN(numValue)) { - // 如果转换结果是 NaN,说明 cartNumber 不是有效的数字字符串,返回 0 - return 0; - } - // type string 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券 - if (item.type === 'weight') { - // 如果类型是称重重量,将值保留两位小数 - return parseFloat(numValue.toFixed(2)); - } else { - // 如果类型是整数,将值转换为整数 - return Math.round(numValue); - } - // 如果类型不匹配,返回原始值 - return item.cartNumber; - }; - }) + const close = () => { emits("close", false) } - // 购物车加减 - const cartListadd = async (item, i) => { - // 是否起售 如果小于或者大于都是1 - const cartNumberFloat = parseFloat(item.cartNumber); - const suitNum = item.suitNum >= cartNumberFloat && i == '-' ? item.cartNumber : 1; + function changeNumber(step,item){ + emits("changeNumber", step, item); - emits('customevent', { - id: item.cartListId ? item.cartListId : '', - type: 'shopping', - table_code: uni.cache.get('tableCode'), - shop_id: uni.cache.get('shopId'), - operate_type: calculateValue(item.cartNumber, i, suitNum) == 'del' ? 'del' : item.cartListId && - item.cartNumber > 0 ? 'edit' : 'add', - product_id: item.id, - sku_id: item.skuId, - number: await calculateValue(item.cartNumber, i, suitNum), - is_print: 1, - suitNum: item.suitNum, - }) } + const dataprocessing = computed(() => { return (item) => { @@ -188,18 +142,6 @@ }; }) - const clickcancelOrder = (i, key) => { - emits('clickcancelOrder', { - i, - key - }) - emits('customevent', { - type: 'shopping', - table_code: uni.cache.get('tableCode'), - shop_id: uni.cache.get('shopId'), - operate_type: 'clearOrder', - }) - } const calculateValue = (cartNumber, i, step = 1) => { if (i == '+') { @@ -212,30 +154,10 @@ } } - // 菜品备注修改 - const productBlur = (item) => { - let params = { - "skuId": item.skuId, - "num": item.number, //数量 - "type": item.type, - "isVip": item.isVip, - "productId": item.productId, //商品id - "note": item.note, - "shopId": this.shopId, - "userId": uni.cache.get('userInfo').id, - "tableId": this.tableCode, - } - this.$emit("addCart", params) - } // 清空购物车 const cartclear = () => { - emits('customevent', { - type: 'shopping', - table_code: uni.cache.get('tableCode'), - shop_id: uni.cache.get('shopId'), - operate_type: 'cleanup', - }) + emits('clearCarts') } diff --git a/pages/product/index - 副本.vue b/pages/product/index - 副本.vue new file mode 100644 index 0000000..369daa9 --- /dev/null +++ b/pages/product/index - 副本.vue @@ -0,0 +1,2631 @@ + + + + + \ No newline at end of file diff --git a/pages/product/index.vue b/pages/product/index.vue index 369daa9..9a605c7 100644 --- a/pages/product/index.vue +++ b/pages/product/index.vue @@ -33,7 +33,7 @@ - + 本店招牌菜 @@ -41,7 +41,7 @@ + v-for="(item,index) in carts.hotgoods" :key="index"> @@ -84,7 +84,7 @@ :class="shopInfo.isVip == 0 || shopInfo.isMemberPrice==0?'lineThrough':''">¥ - {{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(item.memberPrice||item.salePrice):item.salePrice}} + {{carts.useVipPrice?(item.memberPrice||item.salePrice):item.salePrice}} /{{item.unitName}} @@ -106,7 +106,7 @@ :class="shopInfo.isVip ==0 || shopInfo.isMemberPrice==0?'lineThrough':''">¥ - {{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(item.memberPrice|| item.salePrice):item.salePrice}} + {{carts.useVipPrice?(item.memberPrice|| item.salePrice):item.salePrice}} /{{item.unitName}} /{{item1.unitName}} @@ -221,7 +230,7 @@ - {{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(item1.memberPrice||item1.salePrice):item1.salePrice}} + {{carts.useVipPrice?(item1.memberPrice||item1.salePrice):item1.salePrice}} /{{item1.unitName}} - + - + @@ -289,11 +294,11 @@ src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/shopDetails/shopIcon.png" mode="aspectFill" @click="Historicalorders(true)"> - {{cartLists_count<99?cartLists_count:'99+'}} + {{carts.totalNumber <99?carts.totalNumber:'99+'}} - {{totalPrices}} + {{carts.payMoney}} 结算 @@ -366,7 +371,7 @@ {{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1? (specifications.item.result.memberPrice||specifications.item.result.salePrice):specifications.item.result.salePrice}} + class="num">{{carts.useVipPrice? (specifications.item.result.memberPrice||specifications.item.result.salePrice):specifications.item.result.salePrice}} /{{specifications.item.unitName}} 「{{specifications.item.result.suitNum}}{{specifications.item.result.unitName}}起点」 @@ -375,7 +380,7 @@ - {{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1? (specifications.item.memberPrice||specifications.item.salePrice):specifications.item.salePrice}} + {{carts.useVipPrice? (specifications.item.memberPrice||specifications.item.salePrice):specifications.item.salePrice}} /{{specifications.item.unitName}} @@ -418,11 +423,36 @@ 已下单菜品 - + + \ No newline at end of file diff --git a/stores/carts.js b/stores/carts.js deleted file mode 100644 index 9e4015d..0000000 --- a/stores/carts.js +++ /dev/null @@ -1,452 +0,0 @@ -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 - }; - } -); \ No newline at end of file diff --git a/stores/carts.ts b/stores/carts.ts new file mode 100644 index 0000000..e776a06 --- /dev/null +++ b/stores/carts.ts @@ -0,0 +1,821 @@ +import { computed, reactive, ref } from "vue"; +import WebSocketManager, { type ApifoxModel, msgType } from "@/common/js/carts-websocket"; +import { + productminiApphotsquery, + APIgroupquery, + APIminiAppinfo, + APIminiAppskuinfo +} from "@/common/api/product/product.js"; +const shopInfo = uni.cache.get('shopInfo') || { isMemberPrice: false } +export interface CartsState { + id : string | number; + [property : string] : any; +} +import { defineStore } from 'pinia' +import { isProductAvailable, goodsInitParamsFull } from '@/utils/product.js' +function ElMessage() { + +} +export const useCartsStore = defineStore("carts", () => { + //选择用户 + const vipUser = ref<{ id ?: string | number, isVip ?: boolean }>(uni.cache.get('orderVIP') || {}); + function changeUser(user : any) { + vipUser.value = user; + } + + //就餐类型 dine-in take-out + let dinnerType = ref('dine-in'); + + + + //是否启用会员价 + const useVipPrice = computed(() => { + return (shopInfo.isMemberPrice && vipUser.value.id && vipUser.value.isVip) ? true : false + }) + + //台桌id + // const table_code = useStorage('Instead_table_code', ''); + const table_code = ref('') + + //购物车是否初始化连接加载完成 + const isLinkFinshed = ref(false) + //当前购物车数据 + const list = ref([]); + //历史订单数据 + // const oldOrder = useStorage("Instead_olold_order", { + // detailMap: [], + // originAmount: 0 + // }); + const oldOrder = ref({ + detailMap: [], + originAmount: 0 + }) + + //代客下单页面全部商品缓存,包括招牌菜和分组 + const goods = ref([]) + const hotgoods = ref([]) + const groupGoods = ref([]) + async function getGoods(query : any) { + // 招牌菜 + const hotsRes = await productminiApphotsquery({ + ...query, + }); + //分组 + const groupGoodsRes = await APIgroupquery({ + ...query, + }); + hotgoods.value = hotsRes.map(product => { + return goodsInitParamsFull(product) + }) + groupGoods.value = groupGoodsRes.map(v => { + return { + ...v, + productList: v.productList.map(product => { + return goodsInitParamsFull(product) + }) + } + }) + goods.value = [...hotsRes, ...groupGoodsRes.reduce((prve, cur) => { + prve.push(...cur.productList) + return prve + }, [])] + setGoodsMap(goods.value) + } + + function setGoodsMap(goods : any[]) { + for (let item of goods) { + goodsMap[item.id] = item; + } + } + + //赠菜 + const giftList = ref([]) + let goodsMap : { [key : string] : any } = reactive({}); + //当前选中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 + }) + function returnOneGoodsTotalMoney(cur : any) { + const memberPrice = cur.memberPrice || cur.salePrice + const total = cur.number * (useVipPrice.value ? memberPrice : cur.salePrice) + if (cur.type == 'weight') { + return customTruncateToTwoDecimals(total) + } else { + return total + } + } + //赠菜总价 + const giftMoney = computed(() => { + let oldGiftMoney = 0 + for (let i in oldOrder.value.detailMap) { + oldGiftMoney += oldOrder.value.detailMap[i].filter((v : any) => v.isGift).reduce((prve : number, cur : any) => { + const memberPrice = cur.memberPrice || cur.salePrice + return prve + cur.number * (useVipPrice.value ? memberPrice : cur.salePrice) + }, 0) + } + const nowTotal = giftList.value.reduce((acc : number, cur : any) => { + const memberPrice = cur.memberPrice || cur.salePrice + return acc + cur.number * (useVipPrice.value ? memberPrice : cur.salePrice) + }, 0) + return (nowTotal + oldGiftMoney) + }) + //返回打包数量(称重商品打包数量最大为1) + function returnCartPackNumber(cur : any) { + const maxReturnNum = cur.number - (cur.returnNum || 0); + let pack_number = (dinnerType.value == 'take-out' ? cur.number : cur.pack_number * 1); + 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 packNum = computed(() => { + const nowCartNumber = list.value.reduce((acc : number, cur : any) => { + return acc + returnCartPackNumber(cur) + }, 0) + const giftNumber = giftList.value.reduce((acc : number, cur : any) => { + return acc + returnCartPackNumber(cur) + }, 0) + let oldNumber = 0 + for (let i in oldOrder.value.detailMap) { + oldNumber += oldOrder.value.detailMap[i].reduce((prve : number, cur : any) => { + return prve + returnCartPackNumber(cur) + }, 0) + } + return nowCartNumber + giftNumber + oldNumber + }) + + //打包费 + const packFee = computed(() => { + const nowPackFee = list.value.reduce((acc : number, cur : any) => { + return acc + (cur.packFee || 0) * returnCartPackNumber(cur) + }, 0) + const giftPackFee = giftList.value.reduce((acc : number, cur : any) => { + 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 : number, cur : any) => { + return prve + (cur.packFee || 0) * returnCartPackNumber(cur) + }, 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) + const giftTotal = giftList.value.reduce((acc : number, cur : any) => { + const n = (cur.salePrice * 1 - cur.memberPrice * 1) * cur.number + return acc + (n <= 0 ? 0 : n) + }, 0) + let oldTotal = 0; + for (let i in oldOrder.value.detailMap) { + oldTotal += oldOrder.value.detailMap[i].reduce((prve : number, cur : any) => { + const n = (cur.salePrice * 1 - cur.memberPrice * 1) * cur.number + return prve + (n <= 0 ? 0 : n) + }, 0) + } + return listTotal + giftTotal + oldTotal + }) + //单品改价优惠 + 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) { + total += oldOrder.value.detailMap[i].reduce((prve : number, cur : any) => { + 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 = (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 * 1 + 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 = giftList.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; + let pack_number = newNumber < item.pack_number ? (item.pack_number * 1 + step * 1) : item.pack_number * 1; + if (dinnerType.value == 'take-out') { + pack_number = newNumber + } + if (item.product_type == 'weight' && item.pack_number * 1 >= 1) { + pack_number = 1 + } + update({ ...item, number: newNumber, 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 + } + selPlaceNum.value = -1; + isOldOrder.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: '', + product_type: '', + suitNum: 1 + } + //当前购物车直接添加 + 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 | undefined) { + table_code.value = `${newVal}`; + $initParams.table_code = newVal + concocatSocket() + } + //转桌 + function rotTable(newVal : string | number, cart_id = []) { + sendMessage('rottable', { + new_table_code: newVal, + table_code: table_code.value, + cart_id + }); + } + //清空历史订单 + function clearHistory() { + sendMessage('clearOrder', {}); + } + + + function del(data : any) { + sendMessage('del', { id: data.id }); + } + + function update(data : any) { + console.log(data); + const suitNum = data.skuData ? (data.skuData.suitNum || 1) : 1; + if (data.number * 1 < suitNum * 1) { + return sendMessage('del', data); + } + const pack_number = dinnerType.value == 'take-out' ? data.number : data.pack_number + sendMessage('edit', { ...data, suitNum, pack_number }); + } + function updateTag(key : string, val : any, cart : CartsState = selCart.value) { + const skuData = cart.skuData || { suitNum: 1 } + if (cart.number * 1 < skuData.suitNum * 1) { + return sendMessage('del', cart); + } + console.log(key, val) + if (key == 'discount_sale_amount' && val * 1 <= 0) { + // ElMessage.error('价格不能为0!') + return + } + const msg = { ...cart, [key]: val } + if (key == 'number' && dinnerType.value == 'take-out') { + msg.pack_number == val + msg.suitNum == skuData.suitNum + } + + sendMessage('edit', msg); + } + // 更改全部商品打包状态 + function changePack(is_pack : number | string) { + if (!isEmpty.value) { + sendMessage('batch', { is_pack }); + } + } + + 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 = {} + } + + function nowCartsClear() { + if (selPlaceNum.value == 1) { + selListIndex.value = -1; + } + list.value = []; + giftList.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 + } + } + } + + //获取历史订单 + async function getOldOrder(table_code : string | number) { + const res = await orderApi.getHistoryList({ tableCode: table_code }) + console.log('getOldOrder'); + console.log(res); + if (res) { + setOldOrder(res) + } else { + oldOrder.value = { + detailMap: [], + originAmount: 0 + } + } + } + + 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 }) + console.log(skuData) + console.log(v) + + return { + ...v, + ...skuData, + skuData: { + ...skuData, + salePrice: v.price, + memberPrice: v.memberPrice + }, + placeNum: v.placeNum, + number: v.num, + id: v.id, + salePrice: v.price, + memberPrice: v.memberPrice, + pack_number: v.packNumber, + discount_sale_amount: v.discountSaleAmount * 1 || 0, + is_print: v.isPrint, + is_wait_call: v.isWaitCall, + is_gift: v.isGift, + is_temporary: v.isTemporary, + discount_sale_note: v.discountSaleNote, + product_name: v.productName, + sku_name: v.skuName, + sku_id: v.skuId, + product_type: v.productType, + packFee: v.packAmount, + } + }) + } + console.log('newData', newData) + return newData + } + + function setOldOrder(data : any) { + oldOrder.value = { + ...data, + detailMap: returnDetailMap(data.detailMap) + } + } + + let $initParams = {} as ApifoxModel + + + /** + * + * @param initParams 购物车初始化参数 + * @param $goodsMap 商品id对应的map + * @param oldOrder 历史订单数据 + */ + + + + async function init(initParams : ApifoxModel, $oldOrder : any | undefined) { + // 商品id对应的数据map + await getGoods({}) + + if ($oldOrder) { + setOldOrder($oldOrder) + } else { + oldOrder.value = { detailMap: [], originAmount: 0 } + } + + // 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))) + if (initParams) { + initParams.table_code = initParams.table_code ? initParams.table_code : '' + table_code.value = initParams.table_code + $initParams = initParams; + } + console.log($initParams) + // localStorage.setItem('cache_table_code', table_code.value); + concocatSocket($initParams) + } + + function concocatSocket(initParams = $initParams) { + console.log("初始化参数", initParams); + WebSocketManager.subscribeToTopic(initParams, (msg) => { + console.log("收到消息:", msg); + if (msg.hasOwnProperty('status') && msg.status != 1) { + if (msg.type === 'no_suit_num' && selListIndex.value != -1) { + return uni.showModal({ + title: '提示', + showCancel: false, + content: `${list.value[selListIndex.value].name}库存不足`, + success() { + if (res.confirm) { + list.value.splice(selListIndex.value, 1) + } + } + }) + + } + uni.showToast({ + title: msg.message || msg.msg || '操作失败', + icon: 'none' + }) + return + } + if (msg && msg.data) { + if (Array.isArray(msg.data) && msg.data.length && msg.data[0].table_code) { + 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 === "init") { + isLinkFinshed.value = true + // 设置单价 + list.value = msg.data.filter((v : Record) => { + 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) => { + 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 = 'shopping_' + msg.operate_type + } + if (msg.operate_type === "add") { + if (list.value.find(v => v.id == msg.data.id)) { + console.error('该商品已存在') + // ElMessage.warning(msg.message || '该商品已存在') + return + } + const skuData = getProductDetails({ product_id: msg.data.product_id, sku_id: msg.data.sku_id }) + if (skuData || msg.data.is_temporary) { + const newGoods = { ...skuData, ...msg.data } + console.log('新增商品', newGoods) + list.value.push(newGoods) + console.log('添加成功') + // ElMessage.success(msg.message || '添加成功') + return + }else{ + console.error('未找到对应商品'); + } + + + } + if (msg.operate_type === "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 (giftItem) { + //操作赠菜 + if (!newCart.is_gift) { + giftList.value.splice(giftIndex, 1) + list.value.push({ ...giftItem, ...newCart }) + selListIndex.value = -1 + } else { + giftList.value[giftIndex] = { ...giftItem, ...newCart } + } + } + if (cartItem) { + //操作非赠菜 + if (newCart.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 || '修改成功') + } + if (msg.operate_type === "del") { + const cartId = Array.isArray(msg.data) ? msg.data[0].id : msg.data.id + const listIndex = list.value.findIndex((item) => item.id == cartId) + if (listIndex > -1) { + list.value.splice(listIndex, 1) + } + const giftIndex = giftList.value.findIndex((item) => item.id == cartId) + if (giftIndex > -1) { + giftList.value.splice(giftIndex, 1) + } + // ElMessage.success(msg.message || '删除成功') + return + } + if (msg.operate_type === "cleanup") { + nowCartsClear() + getOldOrder(msg.data.table_code) + } + if (msg.operate_type === "batch") { + concocatSocket({ ...$initParams, table_code: table_code.value }) + } + if (msg.operate_type === "clearOrder") { + getOldOrder(msg.data.table_code) + } + if (msg.operate_type === "product_update") { + console.log('商品更新') + init($initParams, oldOrder.value) + } + }); + } + + function disconnect() { + sendMessage('disconnect', undefined) + } + + 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 } + for (let i in delArr) { + delete msg[delArr[i]] + } + console.log('send msg', msg) + WebSocketManager.sendMessage(msg); + } + return { + clearHistory, + disconnect, + dinnerType, + changePack, + giftMoney, + 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, + rotTable, + getGoods, + setGoodsMap, + hotgoods, groupGoods + }; +}); \ No newline at end of file diff --git a/stores/user.js b/stores/user.js index 651562e..f894a77 100644 --- a/stores/user.js +++ b/stores/user.js @@ -214,7 +214,7 @@ export const productStore = defineStore('product', { uni.cache.set('shopUserInfo', res); uni.cache.set('orderVIP', res) uni.cache.set('ordershopUserInfo', res.shopInfo) - resolve(true) + resolve(res) } catch (e) { reject(false) } @@ -226,14 +226,16 @@ export const productStore = defineStore('product', { actionsAPIuser() { return new Promise(async (resolve, reject) => { try { + let res=null // 获取店铺用户会员信息 if (uni.cache.get('shopId')) { - this.actionsproductqueryProduct() + res = await this.actionsproductqueryProduct() } else { - let res = await APIuser() + res = await APIuser() uni.cache.set('userInfo', res); } - resolve(true) + console.log('actionsAPIuser res',res); + resolve(res) } catch (e) { reject(false) } diff --git a/utils/product.js b/utils/product.js new file mode 100644 index 0000000..867489c --- /dev/null +++ b/utils/product.js @@ -0,0 +1,47 @@ +import dayjs from 'dayjs'; +import isBetween from 'dayjs/plugin/isBetween' +dayjs.extend(isBetween) +// 判断商品是否在可售时间内 +export const isProductAvailable = (sellDaysStr, startTimeStr, endTimeStr) => { + // 将后端返回的字符串转换为数组 + const sellDays = sellDaysStr.split(','); + const now = dayjs(); + const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; + const currentDay = days[now.day()]; + + // console.log('当前日期:', currentDay); + // console.log('可售日期列表:', sellDays); + + // 检查当前周几是否在可售周几列表中 + if (!sellDays.includes(currentDay)) { + // console.log('当前日期不在可售日期列表中'); + return false; + } + + const startTime = dayjs(`${now.format('YYYY-MM-DD')} ${startTimeStr}`); + let endTime = dayjs(`${now.format('YYYY-MM-DD')} ${endTimeStr}`); + + // 处理跨天情况 + if (endTime.isBefore(startTime)) { + endTime = endTime.add(1, 'day'); + } + + // console.log('当前时间:', now.format('YYYY-MM-DD HH:mm:ss')); + // console.log('开始时间:', startTime.format('YYYY-MM-DD HH:mm:ss')); + // console.log('结束时间:', endTime.format('YYYY-MM-DD HH:mm:ss')); + + const isInRange = now.isBetween(startTime, endTime, null, '[)'); + // console.log('当前时间是否在可售时间范围内:', isInRange); + + return isInRange; +} + +//点单页面商品数据补充格式化,增加购物车选中数量,增加是否在可售时段内 +export function goodsInitParamsFull(product) { + return { + ...product, + cartNumber: 0, + isSaleTimeshow: isProductAvailable(product.days, product + .startTime, product.endTime) + } +} \ No newline at end of file