@pisell/pisellos 0.0.393 → 0.0.394

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -581,11 +581,20 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
581
581
  var _flatItem$parentProdu2;
582
582
  // 🔥 对于 bundle 子商品,quantity 需要乘以主商品的购买数量
583
583
  var quantity = flatItem.type === 'main' ? product.quantity || 1 : (product.num || 1) * (((_flatItem$parentProdu2 = flatItem.parentProduct) === null || _flatItem$parentProdu2 === void 0 ? void 0 : _flatItem$parentProdu2.quantity) || 1);
584
- applicableProducts.push({
584
+
585
+ // 🔥 传递 parentQuantity 用于差值处理时判断是否是真正的"数量为1"
586
+ var productData = {
585
587
  productId: flatItem._id,
586
588
  amount: Number(product.price || 0),
587
589
  quantity: quantity
588
- });
590
+ };
591
+
592
+ // 子商品需要传递主商品数量
593
+ if (flatItem.type === 'bundle') {
594
+ var _flatItem$parentProdu3;
595
+ productData.parentQuantity = ((_flatItem$parentProdu3 = flatItem.parentProduct) === null || _flatItem$parentProdu3 === void 0 ? void 0 : _flatItem$parentProdu3.quantity) || 1;
596
+ }
597
+ applicableProducts.push(productData);
589
598
  }
590
599
  });
591
600
 
@@ -611,10 +620,10 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
611
620
  product = flatItem.product;
612
621
  originProduct = flatItem.originProduct;
613
622
  } else {
614
- var _flatItem$parentProdu3;
623
+ var _flatItem$parentProdu4;
615
624
  // bundle子商品:构造虚拟商品对象
616
625
  product = {
617
- startDate: flatItem === null || flatItem === void 0 || (_flatItem$parentProdu3 = flatItem.parentProduct) === null || _flatItem$parentProdu3 === void 0 ? void 0 : _flatItem$parentProdu3.startDate,
626
+ startDate: flatItem === null || flatItem === void 0 || (_flatItem$parentProdu4 = flatItem.parentProduct) === null || _flatItem$parentProdu4 === void 0 ? void 0 : _flatItem$parentProdu4.startDate,
618
627
  _id: flatItem._id,
619
628
  id: flatItem.id,
620
629
  price: flatItem.price,
@@ -699,10 +708,10 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
699
708
  product = flatItem.product;
700
709
  originProduct = flatItem.originProduct;
701
710
  } else {
702
- var _flatItem$parentProdu4, _flatItem$bundleItem3, _flatItem$bundleItem4, _flatItem$bundleItem5;
711
+ var _flatItem$parentProdu5, _flatItem$bundleItem3, _flatItem$bundleItem4, _flatItem$bundleItem5;
703
712
  // bundle子商品
704
713
  product = {
705
- startDate: flatItem === null || flatItem === void 0 || (_flatItem$parentProdu4 = flatItem.parentProduct) === null || _flatItem$parentProdu4 === void 0 ? void 0 : _flatItem$parentProdu4.startDate,
714
+ startDate: flatItem === null || flatItem === void 0 || (_flatItem$parentProdu5 = flatItem.parentProduct) === null || _flatItem$parentProdu5 === void 0 ? void 0 : _flatItem$parentProdu5.startDate,
706
715
  _id: flatItem._id,
707
716
  id: flatItem.id,
708
717
  price: flatItem.price,
@@ -848,11 +857,11 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
848
857
  }
849
858
  // bundle子商品:检查自己的 discount_list 或父主商品的 discount_list
850
859
  if (flatItem.type === 'bundle') {
851
- var _product$discount_lis7, _flatItem$parentProdu5;
860
+ var _product$discount_lis7, _flatItem$parentProdu6;
852
861
  if ((_product$discount_lis7 = product.discount_list) !== null && _product$discount_lis7 !== void 0 && _product$discount_lis7.some(function (item) {
853
862
  var _item$discount2;
854
863
  return ((_item$discount2 = item.discount) === null || _item$discount2 === void 0 ? void 0 : _item$discount2.resource_id) === options.discountId;
855
- }) || (_flatItem$parentProdu5 = flatItem.parentProduct) !== null && _flatItem$parentProdu5 !== void 0 && (_flatItem$parentProdu5 = _flatItem$parentProdu5.discount_list) !== null && _flatItem$parentProdu5 !== void 0 && _flatItem$parentProdu5.some(function (item) {
864
+ }) || (_flatItem$parentProdu6 = flatItem.parentProduct) !== null && _flatItem$parentProdu6 !== void 0 && (_flatItem$parentProdu6 = _flatItem$parentProdu6.discount_list) !== null && _flatItem$parentProdu6 !== void 0 && _flatItem$parentProdu6.some(function (item) {
856
865
  var _item$discount3;
857
866
  return ((_item$discount3 = item.discount) === null || _item$discount3 === void 0 ? void 0 : _item$discount3.resource_id) === options.discountId;
858
867
  })) {
@@ -874,14 +883,14 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
874
883
  }
875
884
  // bundle子商品:检查自己的 discount_list 或父主商品的 discount_list
876
885
  if (flatItem.type === 'bundle') {
877
- var _product$discount_lis9, _flatItem$parentProdu6;
886
+ var _product$discount_lis9, _flatItem$parentProdu7;
878
887
  if ((_product$discount_lis9 = product.discount_list) !== null && _product$discount_lis9 !== void 0 && _product$discount_lis9.some(function (item) {
879
888
  var _options$selectedList2;
880
889
  return options === null || options === void 0 || (_options$selectedList2 = options.selectedList) === null || _options$selectedList2 === void 0 ? void 0 : _options$selectedList2.some(function (n) {
881
890
  var _item$discount5;
882
891
  return n.discountId === ((_item$discount5 = item.discount) === null || _item$discount5 === void 0 ? void 0 : _item$discount5.resource_id);
883
892
  });
884
- }) || (_flatItem$parentProdu6 = flatItem.parentProduct) !== null && _flatItem$parentProdu6 !== void 0 && (_flatItem$parentProdu6 = _flatItem$parentProdu6.discount_list) !== null && _flatItem$parentProdu6 !== void 0 && _flatItem$parentProdu6.some(function (item) {
893
+ }) || (_flatItem$parentProdu7 = flatItem.parentProduct) !== null && _flatItem$parentProdu7 !== void 0 && (_flatItem$parentProdu7 = _flatItem$parentProdu7.discount_list) !== null && _flatItem$parentProdu7 !== void 0 && _flatItem$parentProdu7.some(function (item) {
885
894
  var _options$selectedList3;
886
895
  return options === null || options === void 0 || (_options$selectedList3 = options.selectedList) === null || _options$selectedList3 === void 0 ? void 0 : _options$selectedList3.some(function (n) {
887
896
  var _item$discount6;
@@ -1162,7 +1171,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1162
1171
  }));
1163
1172
  }
1164
1173
  } else {
1165
- var _selectedDiscount3$me, _flatItem$parentProdu7;
1174
+ var _selectedDiscount3$me, _flatItem$parentProdu8;
1166
1175
  // 折扣卡:不拆分数量,直接应用
1167
1176
  var _selectedDiscount3 = selectedDiscountCard || applicableDiscounts[0];
1168
1177
  usedDiscounts.set(_selectedDiscount3.id, true);
@@ -1214,7 +1223,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1214
1223
  product_discount_difference: _productDiscountDifference
1215
1224
  }),
1216
1225
  config: _selectedDiscount3 === null || _selectedDiscount3 === void 0 ? void 0 : _selectedDiscount3.config,
1217
- _num: (product.num || 1) * ((flatItem === null || flatItem === void 0 || (_flatItem$parentProdu7 = flatItem.parentProduct) === null || _flatItem$parentProdu7 === void 0 ? void 0 : _flatItem$parentProdu7.num) || 1)
1226
+ _num: (product.num || 1) * ((flatItem === null || flatItem === void 0 || (_flatItem$parentProdu8 = flatItem.parentProduct) === null || _flatItem$parentProdu8 === void 0 ? void 0 : _flatItem$parentProdu8.num) || 1)
1218
1227
  };
1219
1228
 
1220
1229
  // 记录实际应用的折扣
@@ -308,7 +308,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
308
308
  date: string;
309
309
  status: string;
310
310
  week: string;
311
- weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
311
+ weekNum: 0 | 1 | 2 | 3 | 4 | 5 | 6;
312
312
  }[]>;
313
313
  submitTimeSlot(timeSlots: TimeSliceItem): void;
314
314
  private getScheduleDataByIds;
@@ -74,16 +74,17 @@ export declare const isOrderLevelFixedAmountDiscount: (discount: Discount) => bo
74
74
  /**
75
75
  * 计算订单级别固定金额折扣卡的分摊结果
76
76
  * @param discount 折扣卡
77
- * @param applicableProducts 适用商品列表 { productId, amount, quantity }
77
+ * @param applicableProducts 适用商品列表 { productId, amount, quantity, parentQuantity }
78
78
  * @returns 分摊结果 Map<productId, { discountAmount, difference }>
79
79
  * 注意:
80
80
  * - discountAmount 是单价折扣金额(不是总折扣金额)
81
- * - difference(总差值)只会放在最后一个商品上,用于后端补齐金额
81
+ * - difference(总差值)优先直接加到数量为1的单商品折扣上,如果没有则存储在metadata中
82
82
  */
83
83
  export declare const calculateOrderLevelDiscountAllocation: (discount: Discount, applicableProducts: Array<{
84
84
  productId: string | number;
85
85
  amount: number;
86
86
  quantity: number;
87
+ parentQuantity?: number;
87
88
  }>) => Map<string | number, {
88
89
  discountAmount: number;
89
90
  difference: number;
@@ -498,11 +498,11 @@ export var isOrderLevelFixedAmountDiscount = function isOrderLevelFixedAmountDis
498
498
  /**
499
499
  * 计算订单级别固定金额折扣卡的分摊结果
500
500
  * @param discount 折扣卡
501
- * @param applicableProducts 适用商品列表 { productId, amount, quantity }
501
+ * @param applicableProducts 适用商品列表 { productId, amount, quantity, parentQuantity }
502
502
  * @returns 分摊结果 Map<productId, { discountAmount, difference }>
503
503
  * 注意:
504
504
  * - discountAmount 是单价折扣金额(不是总折扣金额)
505
- * - difference(总差值)只会放在最后一个商品上,用于后端补齐金额
505
+ * - difference(总差值)优先直接加到数量为1的单商品折扣上,如果没有则存储在metadata中
506
506
  */
507
507
  export var calculateOrderLevelDiscountAllocation = function calculateOrderLevelDiscountAllocation(discount, applicableProducts) {
508
508
  var result = new Map();
@@ -543,16 +543,71 @@ export var calculateOrderLevelDiscountAllocation = function calculateOrderLevelD
543
543
  allocatedTotal = allocatedTotal.plus(new Decimal(discountAmountPerItem).mul(product.quantity));
544
544
  });
545
545
 
546
- // 🔥 计算总差值,只放在最后一个商品上
546
+ // 🔥 计算总差值
547
547
  // 总差值 = 固定金额 - 所有商品的 (单价折扣 × 数量) 之和
548
548
  var totalDifference = new Decimal(actualDiscountTotal).minus(allocatedTotal).toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber();
549
549
  if (totalDifference > 0) {
550
- var lastProduct = applicableProducts[applicableProducts.length - 1];
551
- var lastProductAllocation = result.get(lastProduct.productId);
552
- if (lastProductAllocation) {
553
- result.set(lastProduct.productId, _objectSpread(_objectSpread({}, lastProductAllocation), {}, {
554
- difference: totalDifference
555
- }));
550
+ // 🔥 判断商品是否是真正的"数量为1"
551
+ // 主商品:quantity === 1
552
+ // 子商品:quantity === 1 且 parentQuantity === 1
553
+ var isSingleQuantity = function isSingleQuantity(product) {
554
+ if (product.parentQuantity !== undefined) {
555
+ // 子商品:需要同时满足自身数量为1且主商品数量为1
556
+ return product.quantity === 1 && product.parentQuantity === 1;
557
+ }
558
+ // 主商品:只需要自身数量为1
559
+ return product.quantity === 1;
560
+ };
561
+
562
+ // 🔥 筛选出数量为1的商品
563
+ var singleQuantityProducts = applicableProducts.filter(isSingleQuantity);
564
+ if (singleQuantityProducts.length > 0) {
565
+ // 🔥 优先级1:找到有足够剩余空间且金额最大的商品
566
+ // 剩余空间 = 商品价格 - 当前折扣金额 >= 差值
567
+ var productsWithEnoughSpace = singleQuantityProducts.filter(function (product) {
568
+ var allocation = result.get(product.productId);
569
+ if (!allocation) return false;
570
+ var remainingSpace = new Decimal(product.amount).minus(allocation.discountAmount).toNumber();
571
+ return remainingSpace >= totalDifference;
572
+ });
573
+ if (productsWithEnoughSpace.length > 0) {
574
+ // 按金额降序排序,选择金额最大的
575
+ productsWithEnoughSpace.sort(function (a, b) {
576
+ return b.amount - a.amount;
577
+ });
578
+ var targetProduct = productsWithEnoughSpace[0];
579
+ var targetAllocation = result.get(targetProduct.productId);
580
+ if (targetAllocation) {
581
+ // 差值直接加到折扣金额上
582
+ result.set(targetProduct.productId, {
583
+ discountAmount: new Decimal(targetAllocation.discountAmount).plus(totalDifference).toNumber(),
584
+ difference: 0 // 不需要存储差值
585
+ });
586
+ }
587
+ } else {
588
+ // 🔥 优先级2:所有数量为1的商品都没有足够剩余空间
589
+ // 选择金额最大的商品,差值存储在metadata中
590
+ singleQuantityProducts.sort(function (a, b) {
591
+ return b.amount - a.amount;
592
+ });
593
+ var _targetProduct = singleQuantityProducts[0];
594
+ var _targetAllocation = result.get(_targetProduct.productId);
595
+ if (_targetAllocation) {
596
+ result.set(_targetProduct.productId, _objectSpread(_objectSpread({}, _targetAllocation), {}, {
597
+ difference: totalDifference
598
+ }));
599
+ }
600
+ }
601
+ } else {
602
+ // 🔥 优先级3:没有数量为1的商品,走原有逻辑
603
+ // 差值存储在最后一个商品的metadata中
604
+ var lastProduct = applicableProducts[applicableProducts.length - 1];
605
+ var lastProductAllocation = result.get(lastProduct.productId);
606
+ if (lastProductAllocation) {
607
+ result.set(lastProduct.productId, _objectSpread(_objectSpread({}, lastProductAllocation), {}, {
608
+ difference: totalDifference
609
+ }));
610
+ }
556
611
  }
557
612
  }
558
613
  return result;
@@ -369,7 +369,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
369
369
  }
370
370
  const applicableProducts = [];
371
371
  sortedFlattenedList.forEach((flatItem) => {
372
- var _a, _b, _c, _d, _e, _f;
372
+ var _a, _b, _c, _d, _e, _f, _g;
373
373
  let product;
374
374
  if (flatItem.type === "main") {
375
375
  product = flatItem.product;
@@ -401,11 +401,15 @@ var RulesModule = class extends import_BaseModule.BaseModule {
401
401
  const isBundleAvailable = this.checkPackageSubItemUsageRules(discount, flatItem);
402
402
  if (isLimitedProduct && isBundleAvailable) {
403
403
  const quantity = flatItem.type === "main" ? product.quantity || 1 : (product.num || 1) * (((_f = flatItem.parentProduct) == null ? void 0 : _f.quantity) || 1);
404
- applicableProducts.push({
404
+ const productData = {
405
405
  productId: flatItem._id,
406
406
  amount: Number(product.price || 0),
407
407
  quantity
408
- });
408
+ };
409
+ if (flatItem.type === "bundle") {
410
+ productData.parentQuantity = ((_g = flatItem.parentProduct) == null ? void 0 : _g.quantity) || 1;
411
+ }
412
+ applicableProducts.push(productData);
409
413
  }
410
414
  });
411
415
  if (applicableProducts.length > 0) {
@@ -308,7 +308,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
308
308
  date: string;
309
309
  status: string;
310
310
  week: string;
311
- weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
311
+ weekNum: 0 | 1 | 2 | 3 | 4 | 5 | 6;
312
312
  }[]>;
313
313
  submitTimeSlot(timeSlots: TimeSliceItem): void;
314
314
  private getScheduleDataByIds;
@@ -74,16 +74,17 @@ export declare const isOrderLevelFixedAmountDiscount: (discount: Discount) => bo
74
74
  /**
75
75
  * 计算订单级别固定金额折扣卡的分摊结果
76
76
  * @param discount 折扣卡
77
- * @param applicableProducts 适用商品列表 { productId, amount, quantity }
77
+ * @param applicableProducts 适用商品列表 { productId, amount, quantity, parentQuantity }
78
78
  * @returns 分摊结果 Map<productId, { discountAmount, difference }>
79
79
  * 注意:
80
80
  * - discountAmount 是单价折扣金额(不是总折扣金额)
81
- * - difference(总差值)只会放在最后一个商品上,用于后端补齐金额
81
+ * - difference(总差值)优先直接加到数量为1的单商品折扣上,如果没有则存储在metadata中
82
82
  */
83
83
  export declare const calculateOrderLevelDiscountAllocation: (discount: Discount, applicableProducts: Array<{
84
84
  productId: string | number;
85
85
  amount: number;
86
86
  quantity: number;
87
+ parentQuantity?: number;
87
88
  }>) => Map<string | number, {
88
89
  discountAmount: number;
89
90
  difference: number;
@@ -345,13 +345,52 @@ var calculateOrderLevelDiscountAllocation = (discount, applicableProducts) => {
345
345
  });
346
346
  const totalDifference = new import_decimal.default(actualDiscountTotal).minus(allocatedTotal).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
347
347
  if (totalDifference > 0) {
348
- const lastProduct = applicableProducts[applicableProducts.length - 1];
349
- const lastProductAllocation = result.get(lastProduct.productId);
350
- if (lastProductAllocation) {
351
- result.set(lastProduct.productId, {
352
- ...lastProductAllocation,
353
- difference: totalDifference
348
+ const isSingleQuantity = (product) => {
349
+ if (product.parentQuantity !== void 0) {
350
+ return product.quantity === 1 && product.parentQuantity === 1;
351
+ }
352
+ return product.quantity === 1;
353
+ };
354
+ const singleQuantityProducts = applicableProducts.filter(isSingleQuantity);
355
+ if (singleQuantityProducts.length > 0) {
356
+ const productsWithEnoughSpace = singleQuantityProducts.filter((product) => {
357
+ const allocation = result.get(product.productId);
358
+ if (!allocation)
359
+ return false;
360
+ const remainingSpace = new import_decimal.default(product.amount).minus(allocation.discountAmount).toNumber();
361
+ return remainingSpace >= totalDifference;
354
362
  });
363
+ if (productsWithEnoughSpace.length > 0) {
364
+ productsWithEnoughSpace.sort((a, b) => b.amount - a.amount);
365
+ const targetProduct = productsWithEnoughSpace[0];
366
+ const targetAllocation = result.get(targetProduct.productId);
367
+ if (targetAllocation) {
368
+ result.set(targetProduct.productId, {
369
+ discountAmount: new import_decimal.default(targetAllocation.discountAmount).plus(totalDifference).toNumber(),
370
+ difference: 0
371
+ // 不需要存储差值
372
+ });
373
+ }
374
+ } else {
375
+ singleQuantityProducts.sort((a, b) => b.amount - a.amount);
376
+ const targetProduct = singleQuantityProducts[0];
377
+ const targetAllocation = result.get(targetProduct.productId);
378
+ if (targetAllocation) {
379
+ result.set(targetProduct.productId, {
380
+ ...targetAllocation,
381
+ difference: totalDifference
382
+ });
383
+ }
384
+ }
385
+ } else {
386
+ const lastProduct = applicableProducts[applicableProducts.length - 1];
387
+ const lastProductAllocation = result.get(lastProduct.productId);
388
+ if (lastProductAllocation) {
389
+ result.set(lastProduct.productId, {
390
+ ...lastProductAllocation,
391
+ difference: totalDifference
392
+ });
393
+ }
355
394
  }
356
395
  }
357
396
  return result;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "0.0.393",
4
+ "version": "0.0.394",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",