diff --git a/.env.development b/.env.development index 16ac0a9..edb49a4 100644 --- a/.env.development +++ b/.env.development @@ -8,13 +8,13 @@ VITE_APP_BASE_API=/dev-api # VITE_APP_API_URL=https://tapi.cashier.sxczgkj.cn/ # 测试 # VITE_APP_API_URL=https://cashier.sxczgkj.com/ # 正式 -VITE_APP_API_URL=http://192.168.0.71/ # 本地 +VITE_APP_API_URL=http://192.168.1.42/ # 本地 # WebSocket 端点(不配置则关闭),线上 ws://api.youlai.tech/ws ,本地 ws://localhost:8989/ws # VITE_APP_WS_ENDPOINT=wss://sockets.sxczgkj.com/wss # VITE_APP_WS_ENDPOINT=wss://czgeatws.sxczgkj.com/wss # 正式 -VITE_APP_WS_ENDPOINT=ws://192.168.0.71:2348 # 本地 +VITE_APP_WS_ENDPOINT=ws://192.168.1.42:2348 # 本地 # 启用 Mock 服务 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 4840797..1ed28cd 100644 --- a/src/views/marketing_center/wisdom_recharge/index.vue +++ b/src/views/marketing_center/wisdom_recharge/index.vue @@ -1,160 +1,129 @@ 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 @@ - + + + +