Commit f47ab5024731acffe34437c09e5a653d15142ce3

Authored by pengye
1 parent b59d5233

付款页筛选后累计获取可叠加的优惠券组合

... ... @@ -528,65 +528,49 @@ Page({
const isValid = validCoupons.some(validCoupon => validCoupon.activity_id == item.activity_id);
item.canCheck = isValid ? '1' : '0'; // 如果在 validCoupons 中,设置 canCheck 为 1,否则为 0
});
// 输入的金额 > 可选券的总优惠金额 勾选所有可选券(未完成)
// let yxDesc=0
// let yxArr=[]
// let yxSum = validCoupons.reduce((pre,cur)=>{
// if (cur.accumulationShow==1 && cur.canCheck == '1') {
// if (cur.desc==0||!cur.desc) {
// yxDesc+=parseFloat(cur.price)
// }else{
// yxDesc+=parseFloat(cur.desc)
// }
// pre+=parseFloat(cur.price)
// yxArr.push(cur)
// }
// return pre;
// },0)
// console.log('yxSum',yxSum,'yxDesc',yxDesc,'yxArr',yxArr);
console.log('可以勾选的券 && 满足付款条件的券', validCoupons);
let stackingCoupons = validCoupons.filter(i => {
return i.accumulationShow == '1'
})
let list1 = []; // 可叠加的优惠券组合
let list2 = []; // 最优惠的不可叠加的优惠券
let finalList = []; //最终用的优惠券组合
// 计算可叠加的组合
let closestSum = -Infinity; // 最接近或等于输入值的和
let descSum = 0;//满减金额之和
function backtrack(startIndex, currentCombination, currentSum,couponCount) {
// 如果当前和等于输入值,直接返回
if (currentSum == amount) {
closestSum = currentSum;
list1 = [...currentCombination];
return;
}
// 如果当前和小于等于输入值且更接近输入值,更新最优解
if (currentSum <= amount && currentSum > closestSum) {
closestSum = currentSum;
list1 = [...currentCombination];
let remainingPrice = amount; // 剩余金额
let totalDiscount = 0; // 总优惠金额
// 1. 优先排序 desc 为空或为 0 的,再根据 price 从大到小排序,再根据满减条件 desc 从大到小排序
stackingCoupons.sort((a, b) => {
if (a.desc === '0' || a.desc === '') return -1; // 优先选择 desc 为空或为 0 的
if (b.desc === '0' || b.desc === '') return 1;
if (parseFloat(b.price) !== parseFloat(a.price)) return parseFloat(b.price) - parseFloat(a.price); // 按 price 从大到小
return parseFloat(b.desc) - parseFloat(a.desc); // 按满减条件 desc 从大到小
});
console.log('排序后的可叠加券列表',stackingCoupons);
// 2. 从排序后的券中选择
for (let coupon of stackingCoupons) {
let couponDesc = parseFloat(coupon.desc);
let couponPrice = parseFloat(coupon.price);
let kyNum = Math.floor(remainingPrice / couponDesc);// 计算券可用张数
if (couponDesc === 0) {// 如果满减条件为 0,直接选择
list1.push(coupon);
remainingPrice -= couponPrice; // 减去价格
totalDiscount += couponPrice; // 计算优惠金额
continue;
}
// 遍历数组
for (let i = startIndex; i < validCoupons.length; i++) {
const obj = validCoupons[i];
if (obj.accumulationShow == '1') { // 仅考虑可叠加的优惠券
if (currentSum*1 + obj.price*1 > amount) continue; // 如果当前和已经超过输入值,跳过
descSum += obj.desc*1;
let remainingPrice = amount - descSum;//输入金额 - 总满减条件金额
let kyNum = Math.floor(remainingPrice/parseFloat(obj.desc))
if (amount - obj.price*1 >= 0&&(!couponCount[obj.aid]||couponCount[obj.aid] < kyNum) && kyNum>-1) {
couponCount[obj.aid] = (couponCount[obj.aid] || 0) + 1; // 更新使用次数
currentCombination.push(obj); // 添加当前数字到组合
backtrack(i + 1, currentCombination, currentSum*1 + obj.price*1,couponCount); // 递归
currentCombination.pop(); // 回溯
couponCount[obj.aid]--; // 回溯时减少使用次数
}
// 提前退出:如果当前和加上当前数字已经小于输入值,后续的数字也会更小
if (currentSum*1 + obj.price*1 < amount) break;
// 如果剩余金额足够,选择券
if (remainingPrice >= couponDesc) {
// 计算实际使用的张数,不能超过 kyNum
let usedCount = Math.min(kyNum, 1); // 假设每次只使用一张
let potentialDiscount = couponDesc * usedCount; // 计算潜在的优惠金额
if (totalDiscount + potentialDiscount <= amount) {// 检查总优惠金额是否会超过总金额
list1.push(coupon);
remainingPrice -= couponPrice * usedCount; // 减去价格
totalDiscount += potentialDiscount; // 计算优惠金额
}
}
// 如果剩余金额已经小于等于 0,停止选择
if (remainingPrice <= 0) break;
}
const couponCount = {};
backtrack(0, [], 0,couponCount); // 开始回溯
// 遍历有效优惠券,寻找不可叠加的优惠券
let maxNonStackableValue = 0
validCoupons.forEach(coupon => {
... ... @@ -607,7 +591,8 @@ Page({
console.log('不可叠加的优惠券', list2);
// 计算两个列表的最大优惠值
let maxStackableValue = list1.reduce((total, coupon) => total + parseFloat(coupon.price), 0);
console.log('可叠加优惠券组合总金额', maxStackableValue);
console.log('不可叠加的优惠券总金额', maxNonStackableValue);
// 比较两个最大值并输出结果
if (maxStackableValue > maxNonStackableValue) {
finalList = list1
... ...