diff --git a/src/store/modules/carts.ts b/src/store/modules/carts.ts index 3ad23d7..e8077fb 100644 --- a/src/store/modules/carts.ts +++ b/src/store/modules/carts.ts @@ -233,6 +233,7 @@ export const useCartsStore = defineStore("carts", () => { const coupons = ref([]); function setCoupons(cps: BackendCoupon[]) { + console.log('setCoupons', cps); coupons.value = cps; } // 优惠券列表 diff --git a/src/utils/goods-utils.js b/src/utils/goods-utils.js index e69de29..1fcc9c4 100644 --- a/src/utils/goods-utils.js +++ b/src/utils/goods-utils.js @@ -0,0 +1,303 @@ +import { BigNumber } from "bignumber.js"; + +/** + * 返回可以抵扣优惠券的商品列表,过滤掉赠品、临时商品,价格从高到低排序 + * @param arr 商品列表 + * @param user 用户信息 + */ +export function returnCanDikouGoods(arr, user) { + return arr + .filter((v) => { + return v.is_temporary != 1 && v.is_gift != 1; + }) + .sort((a, b) => { + return returnGoodsPrice(b, user) - returnGoodsPrice(a, user); + }); +} + +/** + * 返回商品单价 + * @param goods 商品 + * @param user 用户信息 + */ +export function returnGoodsPrice(goods, user) { + if (goods.discount_sale_amount * 1 > 0) { + return goods.discount_sale_amount; + } + if (user.isVip && goods.memberPrice * 1 <= goods.salePrice * 1 && goods.memberPrice * 1 > 0) { + return goods.memberPrice; + } + return goods.salePrice; +} + +/** + * 返回商品分组 + * @param arr 商品列表 + */ +export function returnGoodsGroupMap(arr) { + let map = {}; + arr.forEach((v) => { + const key = v.productId + "_" + v.skuId; + if (!map[key]) { + map[key] = []; + } + map[key].push(v); + }); + return map; +} + +/** + * 优惠券类型:1-满减券,2-商品兑换券,3-折扣券,4-第二件半价券,5-消费送券,6-买一送一券,7-固定价格券,8-免配送费券 + * @param coupon + */ +export function returnCoupType(coupon) { + const couponTypes = { + 1: "满减券", + 2: "商品券", + 3: "折扣券", + 4: "第二件半价券", + 5: "消费送券", + 6: "买一送一券", + 7: "固定价格券", + 8: "免配送费券", + }; + return couponTypes[coupon.type] || "未知类型"; +} + +/** + * 判券是否可用 + * @param canDikouGoodsArr 可抵扣商品列表 + * @param coupon 优惠券 + * @param goodsOrderPrice 商品订单金额 + * @param user 用户信息 + */ +export function returnCouponCanUse(canDikouGoodsArr, coupon, goodsOrderPrice, user) { + if (!coupon.use) { + return false; + } + + // 计算门槛金额 + let fullAmount = goodsOrderPrice; + //是否抵扣全部商品 + const isDikouAll = coupon.useFoods.length === 0; + let canCalcGoodsArr = []; + // 订单里参与门槛计算的商品 + if (!isDikouAll) { + canCalcGoodsArr = canDikouGoodsArr.filter((v) => { + return coupon.useFoods.find((food) => food.id == v.productId); + }); + fullAmount = canCalcGoodsArr.reduce((pre, cur) => { + return pre + returnGoodsPrice(cur, user) * cur.num; + }, 0); + } + + //没有符合商品 + if (!isDikouAll && canCalcGoodsArr.length == 0) { + return false; + } + + //不满足门槛金额 + if (fullAmount < coupon.fullAmount) { + console.log("不满足门槛金额"); + return false; + } + + if (coupon.type == 2) { + //商品券 + return isDikouAll || canCalcGoodsArr.length > 0; + } + if (coupon.type == 1) { + //满减券 + return fullAmount >= coupon.fullAmount; + } + if (coupon.type == 6) { + //买一送一券 + + let canUse = false; + if (isDikouAll) { + canUse = canDikouGoodsArr.some((v) => v.num >= 2); + } + if (canCalcGoodsArr.length > 0) { + canUse = canDikouGoodsArr + .filter((v) => { + return coupon.useFoods.find((food) => food.id == v.productId); + }) + .some((v) => v.num >= 2); + } + return canUse; + } + if (coupon.type == 4) { + //第二件半价券 + let canUse = false; + if (isDikouAll) { + canUse = canDikouGoodsArr.some((v) => v.num >= 2); + } + if (canCalcGoodsArr.length > 0) { + canUse = canDikouGoodsArr + .filter((v) => { + return coupon.useFoods.find((food) => food.id == v.productId); + }) + .some((v) => v.num >= 2); + } + return canUse; + } + if (coupon.type == 3) { + //折扣券 + return false; + } +} + +/** + * 计算抵扣商品金额 + * @param discountGoodsArr 可抵扣商品列表 + * @param discountNum 抵扣数量 + * @param user 用户信息 + */ +export function calcDiscountGoodsArrPrice(discountGoodsArr, discountNum, user) { + let hasCountNum = 0; + let discountPrice = 0; + let hasDiscountGoodsArr = []; + for (let i = 0; i < discountGoodsArr.length; i++) { + if (hasCountNum >= discountNum) { + break; + } + const goods = discountGoodsArr[i]; + const shengyuNum = discountNum - hasCountNum; + const num = Math.min(goods.num, shengyuNum); + discountPrice += returnGoodsPrice(goods, user) * num; + hasCountNum += num; + hasDiscountGoodsArr.push({ ...goods, num }); + } + return { discountPrice, hasDiscountGoodsArr }; +} + +/** + * 计算优惠券抵扣金额 + * @param canDikouGoodsArr 可抵扣商品列表 + * @param coupon 优惠券 + * @param user 用户信息 + */ +export function returnCouponDiscount(canDikouGoodsArr, coupon, user) { + if (coupon.type == 2) { + return returnCouponProductDiscount(canDikouGoodsArr, coupon, user); + } + if (coupon.type == 6) { + return returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user); + } + if (coupon.type == 4) { + return returnSecoendDiscount(canDikouGoodsArr, coupon, user); + } +} + +/** + * 商品券抵扣金额 + * @param canDikouGoodsArr 可抵扣商品列表 + * @param coupon 优惠券 + * @param user 用户信息 + */ +export function returnCouponProductDiscount(canDikouGoodsArr, coupon, user) { + const { useFoods, discountNum, useRule } = coupon; + + //抵扣商品数组 + let discountGoodsArr = []; + + //抵扣全部商品 + if (useFoods.length === 0) { + if (useRule == "price_asc") { + discountGoodsArr = canDikouGoodsArr + .slice(canDikouGoodsArr.length - discountNum, canDikouGoodsArr.length) + .reverse(); + } else { + discountGoodsArr = canDikouGoodsArr.slice(0, discountNum); + } + } else { + //抵扣选中商品 + const discountSelGoodsArr = canDikouGoodsArr.filter((v) => + useFoods.find((food) => food.id == v.productId) + ); + if (useRule == "price_asc") { + discountGoodsArr = discountSelGoodsArr + .slice(discountSelGoodsArr.length - discountNum, discountSelGoodsArr.length) + .reverse(); + } else { + discountGoodsArr = discountSelGoodsArr.slice(0, discountNum); + } + } + const result = calcDiscountGoodsArrPrice(discountGoodsArr, discountNum, user); + console.log(result); + return result; +} + +// 返回买一送一券抵扣详情 +/** + * @param canDikouGoodsArr 可抵扣商品列表 + * @param coupon 优惠券 + * @param user 用户信息 + */ +function returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user) { + const { useFoods, useRule } = coupon; + //抵扣商品 + let discountGoods = undefined; + //符合买一送一条件的商品 + const canUseGoods = canDikouGoodsArr.filter((v) => v.num >= 2); + //抵扣全部商品 + if (useFoods.length === 0) { + if (useRule == "price_asc") { + discountGoods = canUseGoods[canUseGoods.length - 1]; + } else { + discountGoods = canUseGoods.slice(0, 1); + } + } else { + //符合抵扣条件的商品 + const canUseGoods1 = canUseGoods.filter((v) => useFoods.find((food) => food.id == v.productId)); + console.log(canUseGoods1); + if (useRule == "price_asc") { + discountGoods = canUseGoods1[canUseGoods1.length - 1]; + } else { + discountGoods = canUseGoods1.slice(0, 1); + } + } + console.log("discountGoods"); + console.log(discountGoods); + const discountPrice = returnGoodsPrice(discountGoods, user); + const hasDiscountGoodsArr = [discountGoods]; + return { discountPrice, hasDiscountGoodsArr }; +} + +/** + * 返回第二件半价券抵扣详情 + * @param canDikouGoodsArr 可抵扣商品列表 + * @param coupon 优惠券 + * @param user 用户信息 + */ +function returnSecoendDiscount(canDikouGoodsArr, coupon, user) { + const { useFoods, useRule } = coupon; + //抵扣商品 + let discountGoods = undefined; + //符合买一送一条件的商品 + const canUseGoods = canDikouGoodsArr.filter((v) => v.num >= 2); + //抵扣全部商品 + if (useFoods.length === 0) { + if (useRule == "price_asc") { + discountGoods = canUseGoods[canUseGoods.length - 1]; + } else { + discountGoods = canUseGoods.slice(0, 1); + } + } else { + //符合抵扣条件的商品 + const canUseGoods1 = canUseGoods.filter((v) => useFoods.find((food) => food.id == v.productId)); + console.log(canUseGoods1); + if (useRule == "price_asc") { + discountGoods = canUseGoods1[canUseGoods1.length - 1]; + } else { + discountGoods = canUseGoods1.slice(0, 1); + } + } + const discountPrice = returnGoodsPrice(discountGoods, user); + const hasDiscountGoodsArr = [discountGoods]; + //返回半价价格 + return { + discountPrice: new BigNumber(discountPrice).dividedBy(2).toNumber(), + hasDiscountGoodsArr, + }; +} diff --git a/src/utils/goods.ts b/src/utils/goods.ts index 72c0668..3d91bfc 100644 --- a/src/utils/goods.ts +++ b/src/utils/goods.ts @@ -1205,6 +1205,7 @@ export function calcCouponDeduction( excludedProductIds: [] }; } + console.log('toolCoupons', toolCoupons) // 2. 优惠券互斥逻辑:兑换券与其他券互斥,优先选最优 const exchangeCoupons = toolCoupons.filter(c => c.type === CouponType.EXCHANGE); diff --git a/src/views/tool/Instead/components/order.vue b/src/views/tool/Instead/components/order.vue index 99c64fe..72ffbd1 100644 --- a/src/views/tool/Instead/components/order.vue +++ b/src/views/tool/Instead/components/order.vue @@ -289,8 +289,9 @@ function refCouponConfirm(e, goodsList) { pointsDiscountAmount.value = 0; score.sel = -1; console.log("refCouponConfirm", e); - quansSelArr.value = e; carts.setCoupons(e); + + quansSelArr.value = e; checkOrderPay.discountAmount = 0; checkOrderPay.discount = 0; score.sel = -1; diff --git a/src/views/tool/Instead/components/popup-coupon.vue b/src/views/tool/Instead/components/popup-coupon.vue index 28f42d4..7e5b0e4 100644 --- a/src/views/tool/Instead/components/popup-coupon.vue +++ b/src/views/tool/Instead/components/popup-coupon.vue @@ -17,7 +17,7 @@ @@ -103,7 +103,7 @@ @@ -167,7 +167,8 @@