UNPKG

@pisell/pisellos

Version:

一个可扩展的前端模块化SDK框架,支持插件系统

608 lines (548 loc) 26.4 kB
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 */ /** * 获取折扣金额 基于折扣卡类型计算 * 商品券:直接返回商品价格 * 折扣卡:根据折扣卡类型计算 固定金额:直接返回折扣卡金额 百分比:根据折扣卡金额计算 * @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; };