diff --git a/src/utils/goods-utils.js b/src/utils/goods-utils.js index 1fcc9c4..b8ea534 100644 --- a/src/utils/goods-utils.js +++ b/src/utils/goods-utils.js @@ -1,4 +1,5 @@ import { BigNumber } from "bignumber.js"; +import _ from "lodash"; /** * 返回可以抵扣优惠券的商品列表,过滤掉赠品、临时商品,价格从高到低排序 @@ -10,6 +11,9 @@ export function returnCanDikouGoods(arr, user) { .filter((v) => { return v.is_temporary != 1 && v.is_gift != 1; }) + .filter((v) => { + return v.num > 0; + }) .sort((a, b) => { return returnGoodsPrice(b, user) - returnGoodsPrice(a, user); }); @@ -65,17 +69,53 @@ export function returnCoupType(coupon) { } /** - * 判券是否可用 + * 返回商品券抵扣后的商品列表 * @param canDikouGoodsArr 可抵扣商品列表 - * @param coupon 优惠券 - * @param goodsOrderPrice 商品订单金额 + * @param selCoupon 已选择的优惠券列表 * @param user 用户信息 */ -export function returnCouponCanUse(canDikouGoodsArr, coupon, goodsOrderPrice, user) { +export function returnCanDikouGoodsArr(canDikouGoodsArr, selCoupon, user) { + const goodsCouponGoods = selCoupon + .filter((v) => v.type == 2) + .reduce((prve, cur) => { + prve.push(...cur.discount.hasDiscountGoodsArr); + return prve; + }, []); + const arr = _.cloneDeep(canDikouGoodsArr) + .map((v) => { + const findCart = goodsCouponGoods.find((carts) => carts.id == v.id); + if (findCart) { + v.num -= findCart.num; + } + return v; + }) + .filter((v) => v.num > 0); + return arr; +} + +/** + * 判断优惠券是否可使用 + * + * @param {Object} args - 函数参数集合 + * @param {Array} args.canDikouGoodsArr - 可参与抵扣的商品列表,每个元素包含商品信息(productId、num等) + * @param {Object} args.coupon - 优惠券信息对象 + * @param {boolean} args.coupon.use - 优惠券是否启用(true为启用,false为禁用) + * @param {Array} args.coupon.useFoods - 优惠券适用的商品ID列表(空数组表示适用全部商品) + * @param {number} args.coupon.fullAmount - 优惠券使用门槛金额 + * @param {number} args.coupon.type - 优惠券类型(1:满减券, 2:商品券, 3:折扣券, 4:第二件半价券, 6:买一送一券) + * @param {number} args.goodsOrderPrice - 订单中所有商品的总金额(未筛选时的初始金额) + * @param {Object} args.user - 用户信息对象(用于计算商品价格,如会员价等) + * @param {Object} args.user - 用户信息对象(用于计算商品价格,如会员价等) + * @param {Object} args.selCoupon - 已经选择的优惠券信息对象 + * @returns {boolean} - 优惠券是否可用(true可用,false不可用) + */ +export function returnCouponCanUse(args) { + let { canDikouGoodsArr, coupon, goodsOrderPrice, user, selCoupon } = args; if (!coupon.use) { return false; } + canDikouGoodsArr = returnCanDikouGoodsArr(canDikouGoodsArr, selCoupon, user); // 计算门槛金额 let fullAmount = goodsOrderPrice; //是否抵扣全部商品 @@ -143,7 +183,7 @@ export function returnCouponCanUse(canDikouGoodsArr, coupon, goodsOrderPrice, us } if (coupon.type == 3) { //折扣券 - return false; + return true; } } @@ -176,17 +216,65 @@ export function calcDiscountGoodsArrPrice(discountGoodsArr, discountNum, user) { * @param canDikouGoodsArr 可抵扣商品列表 * @param coupon 优惠券 * @param user 用户信息 + * @param goodsOrderPrice 商品订单金额 + * @param selCoupon 已选择的优惠券列表 */ -export function returnCouponDiscount(canDikouGoodsArr, coupon, user) { +export function returnCouponDiscount(canDikouGoodsArr, coupon, user, goodsOrderPrice, selCoupon) { + canDikouGoodsArr = returnCanDikouGoodsArr(canDikouGoodsArr, selCoupon, user); if (coupon.type == 2) { - return returnCouponProductDiscount(canDikouGoodsArr, coupon, user); + return returnCouponProductDiscount(canDikouGoodsArr, coupon, user, goodsOrderPrice); } if (coupon.type == 6) { - return returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user); + return returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user, goodsOrderPrice); } if (coupon.type == 4) { - return returnSecoendDiscount(canDikouGoodsArr, coupon, user); + return returnSecoendDiscount(canDikouGoodsArr, coupon, user, goodsOrderPrice); } + if (coupon.type == 3) { + return returnCouponZhekouDiscount(canDikouGoodsArr, coupon, user, goodsOrderPrice, selCoupon); + } +} + +/** + * 折扣券抵扣金额 + * @param canDikouGoodsArr 可抵扣商品列表 + * @param coupon 优惠券 + * @param user 用户信息 + * @param goodsOrderPrice 商品订单金额 + * @param selCoupon 已选择的优惠券列表 + * + */ +export function returnCouponZhekouDiscount( + canDikouGoodsArr, + coupon, + user, + goodsOrderPrice, + selCoupon +) { + const { discountRate, maxDiscountAmount } = coupon; + + const goodsCouponDiscount = selCoupon + .filter((v) => v.type == 2) + .reduce((prve, cur) => { + return prve + cur.discount.discountPrice; + }, 0); + goodsOrderPrice -= goodsCouponDiscount; + + // 使用bignumber处理高精度计算 + // 1. 计算折扣率(百分比转小数):discountRate / 100 + const discountRatio = new BigNumber(discountRate).dividedBy(100); + // 2. 计算优惠比例:1 - 折扣率(例如:8折的优惠比例是 1 - 0.8 = 0.2) + const discountAmountRatio = new BigNumber(1).minus(discountRatio); + // 3. 计算折扣金额:商品订单金额 × 优惠比例 + let discountPrice = new BigNumber(goodsOrderPrice).times(discountAmountRatio).toNumber(); + if (maxDiscountAmount != 0) { + discountPrice = discountPrice >= maxDiscountAmount ? maxDiscountAmount : discountPrice; + } + + return { + discountPrice, // 折扣抵扣金额(即优惠的金额) + hasDiscountGoodsArr: [], + }; } /** diff --git a/src/utils/goods.ts b/src/utils/goods.ts index 3d91bfc..8b8a43c 100644 --- a/src/utils/goods.ts +++ b/src/utils/goods.ts @@ -269,7 +269,7 @@ export function convertBackendCouponToToolCoupon( currentTime: Date = new Date() ): Coupon | null { // 1. 基础校验:必选字段缺失直接返回null - if (!backendCoupon.id || backendCoupon.couponType === undefined || !backendCoupon.title) { + if (!backendCoupon.id || backendCoupon.type === undefined || !backendCoupon.title) { console.warn('优惠券必选字段缺失', backendCoupon); return null; } diff --git a/src/views/marketing_center/wisdom_recharge/index.vue b/src/views/marketing_center/wisdom_recharge/index.vue index 10d20e6..5b16c4a 100644 --- a/src/views/marketing_center/wisdom_recharge/index.vue +++ b/src/views/marketing_center/wisdom_recharge/index.vue @@ -170,46 +170,46 @@ const AddDialogRef = ref(null); const tabsValue = ref(1); const formRef = ref(null); const form = ref({ - isEnable: 1, - id: "", - shopIdList: "", - useType: "all", - isCustom: 0, - isOrder: 0, - remark: "", - rechargeDetailList: [], + isEnable: 1, + id: "", + shopIdList: "", + useType: "all", + isCustom: 0, + isOrder: 0, + remark: "", + rechargeDetailList: [], }); const rules = ref({ - rechargeDetailList: [ - { - validator: (rule, value, callback) => { - if (form.value.rechargeDetailList.length == 0) { - callback(new Error("请添加面额")); - } else { - callback(); - } - }, - trigger: "change", - }, - ], - remark: [{ required: true, message: "请输入充值说明", trigger: "blur" }], + rechargeDetailList: [ + { + validator: (rule, value, callback) => { + if (form.value.rechargeDetailList.length == 0) { + callback(new Error("请添加面额")); + } else { + callback(); + } + }, + trigger: "change", + }, + ], + remark: [{ required: true, message: "请输入充值说明", trigger: "blur" }], }); function submitHandle() { - formRef.value.validate(async (valid) => { - try { - if (valid) { - await shopRecharge(form.value); - ElNotification({ - title: "注意", - message: "保存成功", - type: "success", - }); - } - } catch (err) { - console.log(err); - } - }); + formRef.value.validate(async (valid) => { + try { + if (valid) { + await shopRecharge(form.value); + ElNotification({ + title: "注意", + message: "保存成功", + type: "success", + }); + } + } catch (err) { + console.log(err); + } + }); } // 点前登录店铺信息 @@ -218,82 +218,83 @@ const shopInfo = ref(""); // 获取分店列表 const branchList = ref([]); async function getBranchPageAjax() { - try { - const res = await getBranchPage(); - branchList.value = res.records; - } catch (err) { - console.log(err); - } + try { + const res = await getBranchPage(); + branchList.value = res.records; + } catch (err) { + console.log(err); + } } function addSuccess(data) { - console.log("addSuccess===", data); - if (data.index == null) { - form.value.rechargeDetailList.push(data.data); - } else { - form.value.rechargeDetailList[data.index] = data.data; - } + console.log("addSuccess===", data); + if (data.index == null) { + form.value.rechargeDetailList.push(data.data); + } else { + form.value.rechargeDetailList[data.index] = data.data; + } } // 获取优惠券列表 const couponList = ref([]); async function couponPageAjax() { - try { - const res = await couponPage({ - page: 1, - size: 500, - }); - couponList.value = res.records; - } catch (err) { - console.log(err); - } + try { + const res = await couponPage({ + page: 1, + size: 500, + }); + couponList.value = res.records; + } catch (err) { + console.log(err); + } } // 用id寻找优惠券名称 function couponListFilter(id) { - if (id) { - let obj = couponList.value.find((item) => item.id == id); - return obj.title; - } else { - return ""; - } + if (id) { + let obj = couponList.value.find((item) => item.id == id); + return obj.title; + } else { + return ""; + } } // 从本地获取商户信息 function getLocalShopInfo() { - shopInfo.value = JSON.parse(localStorage.getItem("userInfo")); + shopInfo.value = JSON.parse(localStorage.getItem("userInfo")); } function back() { - router.back(); + router.back(); } // 配置信息获取 async function shopRechargeGetAjax() { - try { - const res = await shopRechargeGet(); - res.rechargeDetailList.map((item) => { - item.couponInfoList.map((val) => { - val.id = val.coupon.id; - }); - }); - form.value = res; + try { + const res = await shopRechargeGet(); + res.rechargeDetailList.map((item) => { + item.couponInfoList.map((val) => { + val.id = val.coupon ? val.coupon.id : null; + }); + }); + form.value = res; - console.log(form.value); - } catch (err) { - console.log(err); - } + console.log(form.value); + } catch (err) { + console.log(err); + } } onMounted(async () => { - await couponPageAjax(); - getLocalShopInfo(); - getBranchPageAjax(); - shopRechargeGetAjax(); + await couponPageAjax(); + getLocalShopInfo(); + getBranchPageAjax(); + shopRechargeGetAjax(); }); diff --git a/src/views/tool/Instead/components/choose-user.vue b/src/views/tool/Instead/components/choose-user.vue index ceaceff..57e92db 100644 --- a/src/views/tool/Instead/components/choose-user.vue +++ b/src/views/tool/Instead/components/choose-user.vue @@ -77,7 +77,7 @@ const state = reactive({ show: false, query: { name: "", - isVip: 1, + // isVip: 1, }, tableData: { data: [], diff --git a/src/views/tool/Instead/components/popup-coupon.vue b/src/views/tool/Instead/components/popup-coupon.vue index 7e5b0e4..67c3a3a 100644 --- a/src/views/tool/Instead/components/popup-coupon.vue +++ b/src/views/tool/Instead/components/popup-coupon.vue @@ -1,5 +1,5 @@ - + + + +