@pisell/pisellos
Version:
一个可扩展的前端模块化SDK框架,支持插件系统
599 lines (539 loc) • 26.1 kB
JavaScript
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
import Decimal from "decimal.js";
import dayjs from "dayjs";
export var uniqueById = function uniqueById(arr) {
var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'id';
var seen = new Set();
return arr.filter(function (item) {
return !seen.has(item[key]) && seen.add(item[key]);
});
};
// 非预约商品 通过时长和日程判断是否是普通商品
export var isNormalProductByDurationSchedule = function isNormalProductByDurationSchedule(item) {
var _item$schedules, _item$scheduleIds;
return !(item !== null && item !== void 0 && item.duration) && !(item !== null && item !== void 0 && (_item$schedules = item.schedules) !== null && _item$schedules !== void 0 && _item$schedules.length) && !(item !== null && item !== void 0 && (_item$scheduleIds = item['schedule.ids']) !== null && _item$scheduleIds !== void 0 && _item$scheduleIds.length);
};
// 是否全部是普通商品
export var isAllNormalProduct = function isAllNormalProduct(items) {
return items.every(function (item) {
return isNormalProductByDurationSchedule(item);
});
};
/**
* 获取折扣金额 基于折扣卡类型计算
* 商品券:直接返回商品价格
* 折扣卡:根据折扣卡类型计算 固定金额:直接返回折扣卡金额 百分比:根据折扣卡金额计算
* @param discount
* @param total
* @param price
* @returns
*/
export var getDiscountAmount = function getDiscountAmount(discount, total, price) {
var _discount$metadata;
// 商品券
if (discount.tag === 'good_pass') {
return new Decimal(price).minus(new Decimal(price || 0)).toNumber();
}
// 判断是否是固定金额
var isFixedAmount = (discount === null || discount === void 0 || (_discount$metadata = discount.metadata) === null || _discount$metadata === void 0 ? void 0 : _discount$metadata.discount_card_type) === 'fixed_amount';
// 固定金额 小于0时返回0
if (isFixedAmount) {
var _discount$amount;
return Math.max(new Decimal(price).minus(new Decimal(((_discount$amount = discount.amount) !== null && _discount$amount !== void 0 ? _discount$amount : discount.par_value) || 0)).toNumber(), 0);
}
// 百分比:根据折扣卡金额计算
return new Decimal(100).minus(discount.par_value || 0).div(100).mul(new Decimal(price)).toNumber();
};
export var getDiscountListAmountTotal = function getDiscountListAmountTotal(discount) {
return discount.reduce(function (acc, cur) {
return new Decimal(acc).plus(new Decimal(cur.num || 1).mul(new Decimal(cur.amount || 0))).toNumber();
}, new Decimal(0));
};
/**
* 获取折扣金额 计算每个折扣的金额
* @param discount
* @returns
*/
export var getDiscountListAmount = function getDiscountListAmount(discount) {
return discount.reduce(function (acc, cur) {
return new Decimal(acc).plus(new Decimal(cur.amount || 0)).toNumber();
}, new Decimal(0));
};
// 日程项接口定义
// 获取时间是否在日程范围内
export var getDateIsInSchedule = function getDateIsInSchedule(dateTime, scheduleList) {
if (!dateTime || !scheduleList || scheduleList.length === 0) {
return false;
}
var targetDate = dayjs(dateTime);
if (!targetDate.isValid()) {
return false;
}
// 遍历所有日程项
var _iterator = _createForOfIteratorHelper(scheduleList),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var schedule = _step.value;
if (isTimeInScheduleItem(dateTime, schedule)) {
return true;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return false;
};
// 判断时间是否在单个日程项范围内
var isTimeInScheduleItem = function isTimeInScheduleItem(dateTime, schedule) {
var targetDate = dayjs(dateTime);
var targetDateString = dateTime.split(' ')[0]; // YYYY-MM-DD
var targetTimeString = dateTime.split(' ')[1] || '00:00:00'; // HH:mm:ss
switch (schedule.type) {
case 'standard':
return isInStandardSchedule(targetDate, targetDateString, targetTimeString, schedule);
case 'time-slots':
return isInTimeSlotsSchedule(targetDate, targetDateString, targetTimeString, schedule);
case 'designation':
return isInDesignationSchedule(targetDate, targetDateString, targetTimeString, schedule);
default:
return false;
}
};
// 处理标准类型日程
var isInStandardSchedule = function isInStandardSchedule(targetDate, targetDateString, targetTimeString, schedule) {
if (!schedule.start_time || !schedule.end_time) {
return false;
}
var startDate = dayjs(schedule.start_time);
var endDate = dayjs(schedule.end_time);
// 先检查是否在基础时间范围内(不考虑重复)
var isInBasicRange = targetDate.isSameOrAfter(startDate) && targetDate.isSameOrBefore(endDate);
if (schedule.repeat_type === 'none') {
return isInBasicRange;
}
// 处理重复日程
return isInRepeatingSchedule(targetDate, targetDateString, targetTimeString, schedule, startDate, endDate);
};
// 处理时间段类型日程
var isInTimeSlotsSchedule = function isInTimeSlotsSchedule(targetDate, targetDateString, targetTimeString, schedule) {
if (!schedule.start_time) {
return false;
}
// 如果不重复,使用原有逻辑
if (schedule.repeat_type === 'none') {
var scheduleDate = schedule.start_time.split(' ')[0];
// 检查日期是否匹配
if (targetDateString !== scheduleDate) {
return false;
}
// 检查是否在任一时间段内
return checkTimeSlotsForDate(targetDate, targetDateString, schedule.time_slot);
}
// 处理重复日程
return isInTimeSlotsRepeatingSchedule(targetDate, targetDateString, targetTimeString, schedule);
};
// 处理指定类型日程
var isInDesignationSchedule = function isInDesignationSchedule(targetDate, targetDateString, targetTimeString, schedule) {
if (!schedule.designation) {
return false;
}
var _iterator2 = _createForOfIteratorHelper(schedule.designation),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var designation = _step2.value;
var startDateTime = "".concat(designation.start_date, " ").concat(designation.start_time, ":00");
var endDateTime = "".concat(designation.end_date, " ").concat(designation.end_time, ":00");
var startDate = dayjs(startDateTime);
var endDate = dayjs(endDateTime);
if (targetDate.isSameOrAfter(startDate) && targetDate.isSameOrBefore(endDate)) {
return true;
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
return false;
};
// 处理重复日程逻辑
var isInRepeatingSchedule = function isInRepeatingSchedule(targetDate, targetDateString, targetTimeString, schedule, startDate, endDate) {
if (!schedule.repeat_rule) {
return false;
}
var repeat_rule = schedule.repeat_rule,
repeat_type = schedule.repeat_type;
var targetDateOnly = dayjs(targetDateString); // 只取日期部分
// 首先检查是否在包含日期中(包含日期是额外增加的有效日期)
if (repeat_rule.included_date && repeat_rule.included_date.length > 0) {
var _iterator3 = _createForOfIteratorHelper(repeat_rule.included_date),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var includedDate = _step3.value;
var includeStartDate = dayjs(includedDate.start);
var includeEndDate = dayjs(includedDate.end);
if (targetDateOnly.isSameOrAfter(includeStartDate, 'day') && targetDateOnly.isSameOrBefore(includeEndDate, 'day')) {
// 在包含日期中,直接返回true,无需检查其他条件
return true;
}
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
}
// 检查是否在排除日期中
var _iterator4 = _createForOfIteratorHelper(repeat_rule.excluded_date),
_step4;
try {
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
var excludedDate = _step4.value;
var excludeStartDate = dayjs(excludedDate.start);
var excludeEndDate = dayjs(excludedDate.end);
// 检查目标日期是否在排除范围内(包含边界)
if (targetDateOnly.isSameOrAfter(excludeStartDate, 'day') && targetDateOnly.isSameOrBefore(excludeEndDate, 'day')) {
return false;
}
}
// 检查重复规则的结束条件
} catch (err) {
_iterator4.e(err);
} finally {
_iterator4.f();
}
if (repeat_rule.end.type === 'date' && repeat_rule.end.end_date) {
var ruleEndDate = dayjs(repeat_rule.end.end_date);
if (targetDate.isAfter(ruleEndDate)) {
return false;
}
}
// 根据重复类型检查
switch (repeat_type) {
case 'daily':
return isInDailyRepeat(targetDate, startDate, endDate, repeat_rule);
case 'weekly':
return isInWeeklyRepeat(targetDate, startDate, endDate, repeat_rule);
default:
return false;
// 不支持月和年重复
}
};
// 每日重复逻辑
var isInDailyRepeat = function isInDailyRepeat(targetDate, startDate, endDate, repeatRule) {
var daysDiff = targetDate.diff(startDate, 'day');
if (daysDiff < 0) {
return false;
}
// 检查频率
if (daysDiff % repeatRule.frequency !== 0) {
return false;
}
// 检查时间是否在日程的时间范围内
var targetTimeOfDay = targetDate.hour() * 3600 + targetDate.minute() * 60 + targetDate.second();
var startTimeOfDay = startDate.hour() * 3600 + startDate.minute() * 60 + startDate.second();
var endTimeOfDay = endDate.hour() * 3600 + endDate.minute() * 60 + endDate.second();
// 每日重复:每天都在相同的时间段内有效
// 例如:01:00:00 - 16:00:00,每天都是这个时间段
return targetTimeOfDay >= startTimeOfDay && targetTimeOfDay <= endTimeOfDay;
};
// 每周重复逻辑
var isInWeeklyRepeat = function isInWeeklyRepeat(targetDate, startDate, endDate, repeatRule) {
var targetDayOfWeek = targetDate.day(); // 0=周日, 1=周一, ..., 6=周六
// 检查是否在指定的星期几内
if (!repeatRule.frequency_date.includes(targetDayOfWeek)) {
return false;
}
// 计算周差
var weeksDiff = targetDate.diff(startDate, 'week');
if (weeksDiff < 0) {
return false;
}
// 检查频率
if (weeksDiff % repeatRule.frequency !== 0) {
return false;
}
// 检查时间是否在日程的时间范围内
var targetTimeOfDay = targetDate.hour() * 3600 + targetDate.minute() * 60 + targetDate.second();
var startTimeOfDay = startDate.hour() * 3600 + startDate.minute() * 60 + startDate.second();
var endTimeOfDay = endDate.hour() * 3600 + endDate.minute() * 60 + endDate.second();
return targetTimeOfDay >= startTimeOfDay && targetTimeOfDay <= endTimeOfDay;
};
// 处理 time-slots 类型的重复日程
var isInTimeSlotsRepeatingSchedule = function isInTimeSlotsRepeatingSchedule(targetDate, targetDateString, targetTimeString, schedule) {
if (!schedule.repeat_rule || !schedule.start_time) {
return false;
}
var repeat_rule = schedule.repeat_rule,
repeat_type = schedule.repeat_type;
var startDate = dayjs(schedule.start_time);
var targetDateOnly = dayjs(targetDateString);
// 检查包含日期
if (repeat_rule.included_date && repeat_rule.included_date.length > 0) {
var _iterator5 = _createForOfIteratorHelper(repeat_rule.included_date),
_step5;
try {
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
var includedDate = _step5.value;
var includeStartDate = dayjs(includedDate.start);
var includeEndDate = dayjs(includedDate.end);
if (targetDateOnly.isSameOrAfter(includeStartDate, 'day') && targetDateOnly.isSameOrBefore(includeEndDate, 'day')) {
// 在包含日期中,检查时间段
return checkTimeSlotsForDate(targetDate, targetDateString, schedule.time_slot);
}
}
} catch (err) {
_iterator5.e(err);
} finally {
_iterator5.f();
}
}
// 检查排除日期
var _iterator6 = _createForOfIteratorHelper(repeat_rule.excluded_date),
_step6;
try {
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
var excludedDate = _step6.value;
var excludeStartDate = dayjs(excludedDate.start);
var excludeEndDate = dayjs(excludedDate.end);
if (targetDateOnly.isSameOrAfter(excludeStartDate, 'day') && targetDateOnly.isSameOrBefore(excludeEndDate, 'day')) {
return false;
}
}
// 检查重复规则的结束条件
} catch (err) {
_iterator6.e(err);
} finally {
_iterator6.f();
}
if (repeat_rule.end.type === 'date' && repeat_rule.end.end_date) {
var ruleEndDate = dayjs(repeat_rule.end.end_date);
if (targetDateOnly.isAfter(ruleEndDate, 'day')) {
return false;
}
}
// 检查目标日期是否在重复规则范围内
var isDateValid = false;
switch (repeat_type) {
case 'daily':
isDateValid = isInDailyRepeatForDate(targetDateOnly, startDate, repeat_rule);
break;
case 'weekly':
isDateValid = isInWeeklyRepeatForDate(targetDateOnly, startDate, repeat_rule);
break;
default:
return false;
}
// 如果日期有效,检查时间段
if (isDateValid) {
return checkTimeSlotsForDate(targetDate, targetDateString, schedule.time_slot);
}
return false;
};
// 检查目标时间是否在某个时间段内(使用目标日期 + time_slot 时间)
var checkTimeSlotsForDate = function checkTimeSlotsForDate(targetDate, targetDateString, timeSlots) {
var _iterator7 = _createForOfIteratorHelper(timeSlots),
_step7;
try {
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
var timeSlot = _step7.value;
var slotStart = "".concat(targetDateString, " ").concat(timeSlot.start_time, ":00");
var slotEnd = "".concat(targetDateString, " ").concat(timeSlot.end_time, ":00");
var slotStartDate = dayjs(slotStart);
var slotEndDate = dayjs(slotEnd);
if (targetDate.isSameOrAfter(slotStartDate) && targetDate.isSameOrBefore(slotEndDate)) {
return true;
}
}
} catch (err) {
_iterator7.e(err);
} finally {
_iterator7.f();
}
return false;
};
// 检查日期是否满足每日重复规则(只检查日期,不检查时间)
var isInDailyRepeatForDate = function isInDailyRepeatForDate(targetDate, startDate, repeatRule) {
var daysDiff = targetDate.diff(startDate, 'day');
if (daysDiff < 0) {
return false;
}
// 检查频率
return daysDiff % repeatRule.frequency === 0;
};
// 检查日期是否满足每周重复规则(只检查日期,不检查时间)
var isInWeeklyRepeatForDate = function isInWeeklyRepeatForDate(targetDate, startDate, repeatRule) {
var targetDayOfWeek = targetDate.day(); // 0=周日, 1=周一, ..., 6=周六
// 检查是否在指定的星期几内
if (!repeatRule.frequency_date.includes(targetDayOfWeek)) {
return false;
}
// 计算周差
var weeksDiff = targetDate.diff(startDate, 'week');
if (weeksDiff < 0) {
return false;
}
// 检查频率
return weeksDiff % repeatRule.frequency === 0;
};
/**
* 根据预约时间过滤优惠券列表
* @param discountList 优惠券列表
* @param bookingTime 预约时间 (格式: YYYY-MM-DD HH:mm:ss)
* @returns 过滤后的优惠券列表
*/
export var filterDiscountListByBookingTime = function filterDiscountListByBookingTime(discountList, bookingTime) {
if (!bookingTime) {
return discountList;
}
return discountList.filter(function (discount) {
var _discount$metadata2;
if ((discount === null || discount === void 0 || (_discount$metadata2 = discount.metadata) === null || _discount$metadata2 === void 0 ? void 0 : _discount$metadata2.validity_type) === "custom_schedule_validity") {
var _discount$custom_sche;
return getDateIsInSchedule(bookingTime, ((_discount$custom_sche = discount.custom_schedule_snapshot) === null || _discount$custom_sche === void 0 ? void 0 : _discount$custom_sche.data) || []);
}
try {
var isHasStart = !!discount.start_date && !!discount.start_time;
var startDate = dayjs("".concat(discount.start_date, " ").concat(discount.start_time));
var bookingTimeDayjs = dayjs(bookingTime);
// 判断预约时间是否在开始时间之后
var isAfterStart = isHasStart ? bookingTimeDayjs.isSameOrAfter(startDate) : true;
// 判断预约时间是否在过期时间之前(expire_time 为空时为长期有效)
var isBeforeExpire = discount.expire_time ? bookingTimeDayjs.isSameOrBefore(dayjs(discount.expire_time)) : true;
return isAfterStart && isBeforeExpire;
} catch (error) {
return true;
}
});
};
/**
* 判断是否是订单级别的固定金额折扣卡
* @param discount 折扣
* @returns 是否是订单级别的固定金额折扣卡
*/
export var isOrderLevelFixedAmountDiscount = function isOrderLevelFixedAmountDiscount(discount) {
var _discount$metadata3, _discount$metadata4;
return discount.tag === 'product_discount_card' && (discount === null || discount === void 0 || (_discount$metadata3 = discount.metadata) === null || _discount$metadata3 === void 0 ? void 0 : _discount$metadata3.discount_card_type) === 'fixed_amount' && (discount === null || discount === void 0 || (_discount$metadata4 = discount.metadata) === null || _discount$metadata4 === void 0 ? void 0 : _discount$metadata4.discount_calculation_mode) === 'order_level';
};
/**
* 计算订单级别固定金额折扣卡的分摊结果
* @param discount 折扣卡
* @param applicableProducts 适用商品列表 { productId, amount, quantity, parentQuantity }
* @returns 分摊结果 Map<productId, { discountAmount, difference }>
* 注意:
* - discountAmount 是单价折扣金额(不是总折扣金额)
* - difference(总差值)优先直接加到数量为1的单商品折扣上,如果没有则存储在metadata中
*/
export var calculateOrderLevelDiscountAllocation = function calculateOrderLevelDiscountAllocation(discount, applicableProducts) {
var result = new Map();
if (applicableProducts.length === 0) {
return result;
}
// 计算适用商品的总金额(数量 × 单价)
var totalAmount = applicableProducts.reduce(function (acc, product) {
return new Decimal(acc).plus(new Decimal(product.amount).mul(product.quantity)).toNumber();
}, 0);
if (totalAmount <= 0) {
return result;
}
// 固定减免金额
var fixedAmount = new Decimal(discount.par_value || 0).toNumber();
// 如果固定金额 >= 商品总金额,折扣最高为商品金额(免费)
var actualDiscountTotal = Math.min(fixedAmount, totalAmount);
// 计算每个商品的单价折扣金额
var allocatedTotal = new Decimal(0);
applicableProducts.forEach(function (product) {
// 🔥 分摊公式改为:(单价 / 适用商品总金额) × 固定金额
// 这样只有一次取整,避免精度损失
var rawDiscountPerItem = new Decimal(product.amount).div(totalAmount).mul(actualDiscountTotal);
// 保留两位小数,向下取整(单价折扣)
var discountAmountPerItem = rawDiscountPerItem.toDecimalPlaces(2, Decimal.ROUND_DOWN).toNumber();
result.set(product.productId, {
discountAmount: discountAmountPerItem,
// 单价折扣金额
difference: 0 // 默认差值为0
});
// 累加实际分配的总折扣金额(单价折扣 × 数量)
allocatedTotal = allocatedTotal.plus(new Decimal(discountAmountPerItem).mul(product.quantity));
});
// 🔥 计算总差值
// 总差值 = 固定金额 - 所有商品的 (单价折扣 × 数量) 之和
var totalDifference = new Decimal(actualDiscountTotal).minus(allocatedTotal).toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber();
if (totalDifference > 0) {
// 🔥 判断商品是否是真正的"数量为1"
// 主商品:quantity === 1
// 子商品:quantity === 1 且 parentQuantity === 1
var isSingleQuantity = function isSingleQuantity(product) {
if (product.parentQuantity !== undefined) {
// 子商品:需要同时满足自身数量为1且主商品数量为1
return product.quantity === 1 && product.parentQuantity === 1;
}
// 主商品:只需要自身数量为1
return product.quantity === 1;
};
// 🔥 筛选出数量为1的商品
var singleQuantityProducts = applicableProducts.filter(isSingleQuantity);
if (singleQuantityProducts.length > 0) {
// 🔥 优先级1:找到有足够剩余空间且金额最大的商品
// 剩余空间 = 商品价格 - 当前折扣金额 >= 差值
var productsWithEnoughSpace = singleQuantityProducts.filter(function (product) {
var allocation = result.get(product.productId);
if (!allocation) return false;
var remainingSpace = new Decimal(product.amount).minus(allocation.discountAmount).toNumber();
return remainingSpace >= totalDifference;
});
if (productsWithEnoughSpace.length > 0) {
// 按金额降序排序,选择金额最大的
productsWithEnoughSpace.sort(function (a, b) {
return b.amount - a.amount;
});
var targetProduct = productsWithEnoughSpace[0];
var targetAllocation = result.get(targetProduct.productId);
if (targetAllocation) {
// 差值直接加到折扣金额上
result.set(targetProduct.productId, {
discountAmount: new Decimal(targetAllocation.discountAmount).plus(totalDifference).toNumber(),
difference: 0 // 不需要存储差值
});
}
} else {
// 🔥 优先级2:所有数量为1的商品都没有足够剩余空间
// 选择金额最大的商品,差值存储在metadata中
singleQuantityProducts.sort(function (a, b) {
return b.amount - a.amount;
});
var _targetProduct = singleQuantityProducts[0];
var _targetAllocation = result.get(_targetProduct.productId);
if (_targetAllocation) {
result.set(_targetProduct.productId, _objectSpread(_objectSpread({}, _targetAllocation), {}, {
difference: totalDifference
}));
}
}
} else {
// 🔥 优先级3:没有数量为1的商品,走原有逻辑
// 差值存储在最后一个商品的metadata中
var lastProduct = applicableProducts[applicableProducts.length - 1];
var lastProductAllocation = result.get(lastProduct.productId);
if (lastProductAllocation) {
result.set(lastProduct.productId, _objectSpread(_objectSpread({}, lastProductAllocation), {}, {
difference: totalDifference
}));
}
}
}
return result;
};