霸王餐,满减活动等问题修复

This commit is contained in:
2025-10-17 20:22:59 +08:00
parent d858a34698
commit 5d98b7efc2
7 changed files with 239 additions and 129 deletions

View File

@@ -288,7 +288,7 @@ export interface OrderCostSummary {
actualAmount: number; // 满减实际减免金额(元)
};
// 订单原支付金额
orderOriginFinalPayAmount: number; //订单原金额(包含打包费+餐位费)
orderOriginFinalPayAmount: number; //订单原金额(包含打包费+餐位费)
}
/** 满减活动阈值单条满减规则满X减Y- 对应 MkDiscountThresholdInsertGroupDefaultGroup */
@@ -414,7 +414,6 @@ export function filterOptimalFullReductionActivity(
currentTime: Date = new Date()
): FullReductionActivity | undefined {
if (!activities || !activities.length) return undefined;
console.log("原始满减活动列表:", activities);
// 第一步:基础筛选(未删除+当前店铺+活动进行中+就餐类型匹配)
const baseEligible = activities.filter((activity) => {
return (
@@ -425,7 +424,6 @@ export function filterOptimalFullReductionActivity(
activity.thresholds?.length // 至少有一个满减阈值
);
});
console.log("基础筛选结果:", baseEligible);
if (!baseEligible.length) return undefined;
// 第二步:时间筛选(有效期内+周期内+时段内)
@@ -814,10 +812,7 @@ export function selectOptimalThreshold(
if (!thresholds.length) return undefined;
// 第一步确定满减门槛基数根据discountShare规则
const thresholdBase =
discountShare === 1
? new BigNumber(goodsRealAmount) // 与限时折扣同享→用折扣后金额
: new BigNumber(goodsOriginalAmount); // 不同享→用原价
const thresholdBase = baseAmount;
// 第二步:筛选「满金额≤基数」且「减免金额>0」的有效阈值
const validThresholds = thresholds.filter((threshold) => {
@@ -830,21 +825,34 @@ export function selectOptimalThreshold(
});
if (!validThresholds.length) return undefined;
// 第三步选择最优阈值优先级1.满金额最小 → 2.减免金额最大)
return validThresholds.sort((a, b) => {
const aFull = new BigNumber(a.fullAmount || 0);
const bFull = new BigNumber(b.fullAmount || 0);
const aDiscount = new BigNumber(a.discountAmount || 0);
const bDiscount = new BigNumber(b.discountAmount || 0);
// const sortValidThresholds = validThresholds.sort((a, b) => {
// const aFull = new BigNumber(a.fullAmount || 0);
// const bFull = new BigNumber(b.fullAmount || 0);
// const aDiscount = new BigNumber(a.discountAmount || 0);
// const bDiscount = new BigNumber(b.discountAmount || 0);
// 先比满金额越小越优先满1减10 比 满100减20 更优)
if (!aFull.isEqualTo(bFull)) {
return aFull.comparedTo(bFull) || 0; // Ensure a number is always returned
}
// 再比减免金额:越大越优先
return bDiscount.comparedTo(aDiscount) || 0; // Ensure a number is always returned
})[0];
// // 先比满金额越小越优先满1减10 比 满100减20 更优)
// if (!aFull.isEqualTo(bFull)) {
// return aFull.comparedTo(bFull) || 0; // Ensure a number is always returned
// }
// // 再比减免金额:越大越优先
// return bDiscount.comparedTo(aDiscount) || 0; // Ensure a number is always returned
// })
// 找到抵扣金额最大的门槛项
const maxDiscountThreshold = validThresholds.reduce(
(maxItem, currentItem) => {
// 处理空值默认抵扣金额为0
const maxDiscount = new BigNumber(maxItem?.discountAmount || 0);
const currentDiscount = new BigNumber(currentItem?.discountAmount || 0);
// 比较当前项和已存最大项的抵扣金额,保留更大的
return currentDiscount.gt(maxDiscount) ? currentItem : maxItem;
},
validThresholds[0] || null
); // 初始值为数组第一项若数组为空则返回null
console.log("maxDiscountThreshold", maxDiscountThreshold);
return maxDiscountThreshold;
}
/**
@@ -1016,6 +1024,7 @@ export function calcPointDeduction(
deductionAmount: number;
usedPoints: number;
} {
console.log("calcPointDeduction", userPoints, rule, maxDeductionLimit);
if (rule.pointsPerYuan <= 0 || userPoints <= 0) {
return { deductionAmount: 0, usedPoints: 0 };
}
@@ -1098,12 +1107,21 @@ export function calculateOrderCostSummary(
currentTime
);
// 其他费用计算(原有逻辑不变) ------------------------------
const packFee = calcTotalPackFee(goodsList, dinnerType); // 打包费
let seatFee = calcSeatFee(config.seatFeeConfig); // 餐位费
seatFee = dinnerType === "dine-in" ? seatFee : 0; // 外卖不收餐位费
const additionalFee = Math.max(0, config.additionalFee); // 附加费
// 2.2 计算满减基数(先扣新客立减)
const baseAfterNewUserDiscount = new BigNumber(goodsRealAmount)
let baseAfterNewUserDiscount = new BigNumber(goodsRealAmount)
.minus(newUserDiscount)
.isGreaterThan(0)
? new BigNumber(goodsRealAmount).minus(newUserDiscount).toNumber()
: 0;
.plus(packFee)
.plus(seatFee)
.plus(additionalFee)
.toNumber();
baseAfterNewUserDiscount =
baseAfterNewUserDiscount > 0 ? baseAfterNewUserDiscount : 0;
// 2.3 选择最优满减阈值(多门槛场景)
if (usedFullReductionActivity) {
@@ -1122,7 +1140,6 @@ export function calculateOrderCostSummary(
usedFullReductionThreshold
);
}
// ------------------------------ 3. 优惠券抵扣(适配满减同享规则) ------------------------------
let couponDeductionAmount = 0;
let productCouponDeduction = 0;
@@ -1144,7 +1161,6 @@ export function calculateOrderCostSummary(
currentTime,
}
);
console.log("优惠券计算结果", couponResult);
couponDeductionAmount = couponResult.deductionAmount;
productCouponDeduction = couponResult.productCouponDeduction;
fullCouponDeduction = couponResult.fullCouponDeduction;
@@ -1153,46 +1169,49 @@ export function calculateOrderCostSummary(
// 若满减与优惠券同享couponShare=1才计算优惠券否则优惠券抵扣为0
if (usedFullReductionActivity && !usedFullReductionActivity.couponShare) {
couponDeductionAmount=0;
productCouponDeduction=0;
fullCouponDeduction=0;
usedCoupon=undefined;
excludedProductIds=[];
couponDeductionAmount = 0;
productCouponDeduction = 0;
fullCouponDeduction = 0;
usedCoupon = undefined;
excludedProductIds = [];
}
// ------------------------------ 4. 积分抵扣(适配满减同享规则) ------------------------------
let pointDeductionAmount = 0;
let usedPoints = 0;
// 计算积分抵扣基数(商品折扣后 - 新客立减 - 满减 - 优惠券)
const maxPointDeductionLimit = new BigNumber(goodsRealAmount)
// 计算积分抵扣基数(商品折扣后 - 新客立减 - 满减 - 优惠券 + 餐位费 + 打包费 + 附加费
let maxPointDeductionLimit = new BigNumber(goodsRealAmount)
.minus(newUserDiscount)
.minus(fullReductionAmount)
.minus(couponDeductionAmount)
.isGreaterThan(0)
? new BigNumber(goodsRealAmount)
.minus(newUserDiscount)
.minus(fullReductionAmount)
.minus(couponDeductionAmount)
.toNumber()
: 0;
.plus(seatFee)
.plus(packFee)
.plus(additionalFee)
.toNumber();
maxPointDeductionLimit =
maxPointDeductionLimit > 0 ? maxPointDeductionLimit : 0;
// 若满减与积分同享pointsShare=1才计算积分否则积分抵扣为0
if (
usedFullReductionActivity?.pointsShare === 1 &&
maxPointDeductionLimit > 0
) {
const pointResult = calcPointDeduction(
config.userPoints,
config.pointDeductionRule,
maxPointDeductionLimit
);
pointDeductionAmount = pointResult.deductionAmount;
usedPoints = pointResult.usedPoints;
const pointResult = calcPointDeduction(
config.userPoints,
config.pointDeductionRule,
maxPointDeductionLimit
);
console.log("积分抵扣结果:", pointResult);
pointDeductionAmount = pointResult.deductionAmount;
usedPoints = pointResult.usedPoints;
// 若满减与积分不同享pointsShare=1积分抵扣为0
if (usedFullReductionActivity && !usedFullReductionActivity.pointsShare) {
console.log("满减与积分不同享:积分抵扣为0");
pointDeductionAmount = 0;
usedPoints = 0;
}
//使用霸王餐
if (isFreeDine && freeDineConfig && freeDineConfig.enable) {
console.log("使用霸王餐");
//不与优惠券同享
if (!freeDineConfig.withCoupon) {
couponDeductionAmount = 0;
@@ -1208,12 +1227,6 @@ export function calculateOrderCostSummary(
}
}
// ------------------------------ 5. 其他费用计算(原有逻辑不变) ------------------------------
const packFee = calcTotalPackFee(goodsList, dinnerType); // 打包费
let seatFee = calcSeatFee(config.seatFeeConfig); // 餐位费
seatFee = dinnerType === "dine-in" ? seatFee : 0; // 外卖不收餐位费
const additionalFee = Math.max(0, config.additionalFee); // 附加费
// 商家减免计算(原有逻辑不变)
const merchantReductionConfig = config.merchantReduction;
let merchantReductionActualAmount = 0;
@@ -1270,7 +1283,7 @@ export function calculateOrderCostSummary(
truncateToTwoDecimals(finalPayAmountBn.toNumber())
);
// ------------------------------ 使用霸王餐计算 ------------------------------
let orderOriginFinalPayAmount=finalPayAmount;
let orderOriginFinalPayAmount = finalPayAmount;
if (isFreeDine && freeDineConfig && freeDineConfig.enable) {
finalPayAmount = BigNumber(finalPayAmount)
.times(freeDineConfig.rechargeTimes)