@pisell/pisellos 2.1.170 → 2.1.172
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.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -3
- package/dist/model/strategy/adapter/index.d.ts +0 -4
- package/dist/model/strategy/adapter/index.js +1 -5
- package/dist/model/strategy/adapter/promotion/evaluator.js +99 -26
- package/dist/model/strategy/adapter/promotion/index.js +0 -9
- package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
- package/dist/model/strategy/adapter/walletPass/evaluator.js +61 -8
- package/dist/model/strategy/adapter/walletPass/locales.js +12 -3
- package/dist/model/strategy/engine.d.ts +18 -5
- package/dist/model/strategy/engine.js +145 -45
- package/dist/model/strategy/type.d.ts +17 -0
- package/dist/model/strategy/type.js +4 -0
- package/dist/modules/Cart/types.d.ts +2 -0
- package/dist/modules/Cart/utils/cartProduct.js +56 -25
- package/dist/modules/Cart/utils/changePrice.js +9 -16
- package/dist/modules/Discount/index.d.ts +4 -13
- package/dist/modules/Discount/index.js +12 -124
- package/dist/modules/Discount/types.d.ts +18 -13
- package/dist/modules/Order/index.d.ts +1 -67
- package/dist/modules/Order/index.js +30 -918
- package/dist/modules/Order/types.d.ts +12 -176
- package/dist/modules/Order/types.js +0 -2
- package/dist/modules/Order/utils.d.ts +0 -118
- package/dist/modules/Order/utils.js +2 -586
- package/dist/modules/Payment/index.d.ts +2 -1
- package/dist/modules/Payment/index.js +10 -7
- package/dist/modules/Payment/utils.js +3 -0
- package/dist/modules/Payment/walletpass.d.ts +23 -0
- package/dist/modules/Payment/walletpass.js +191 -95
- package/dist/modules/Product/utils.js +2 -2
- package/dist/modules/ProductList/index.d.ts +2 -4
- package/dist/modules/ProductList/index.js +12 -24
- package/dist/modules/Rules/index.d.ts +9 -5
- package/dist/modules/Rules/index.js +669 -173
- package/dist/modules/Rules/types.d.ts +2 -0
- package/dist/modules/Schedule/getDateIsInSchedule.js +18 -16
- package/dist/modules/Schedule/utils.d.ts +1 -1
- package/dist/modules/Summary/types.d.ts +2 -0
- package/dist/modules/Summary/utils.d.ts +9 -3
- package/dist/modules/Summary/utils.js +57 -67
- package/dist/modules/index.d.ts +0 -4
- package/dist/modules/index.js +1 -5
- package/dist/plugins/window.d.ts +2 -0
- package/dist/solution/BookingByStep/index.d.ts +3 -2
- package/dist/solution/BookingByStep/index.js +43 -46
- package/dist/solution/BookingByStep/types.d.ts +1 -3
- package/dist/solution/BookingByStep/types.js +1 -5
- package/dist/solution/BookingByStep/utils/timeslots.d.ts +1 -3
- package/dist/solution/BookingByStep/utils/timeslots.js +12 -19
- package/dist/solution/Checkout/index.js +2 -0
- package/dist/solution/ShopDiscount/index.d.ts +2 -3
- package/dist/solution/ShopDiscount/index.js +60 -62
- package/dist/solution/ShopDiscount/types.d.ts +1 -1
- package/dist/solution/ShopDiscount/types.js +2 -1
- package/dist/solution/ShopDiscount/utils.js +26 -12
- package/dist/solution/index.d.ts +0 -2
- package/dist/solution/index.js +1 -3
- package/lib/index.d.ts +1 -1
- package/lib/index.js +3 -4
- package/lib/model/strategy/adapter/index.d.ts +0 -4
- package/lib/model/strategy/adapter/index.js +2 -13
- package/lib/model/strategy/adapter/promotion/evaluator.js +57 -8
- package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
- package/lib/model/strategy/adapter/walletPass/evaluator.js +34 -3
- package/lib/model/strategy/adapter/walletPass/locales.js +12 -3
- package/lib/model/strategy/engine.d.ts +18 -5
- package/lib/model/strategy/engine.js +85 -21
- package/lib/model/strategy/type.d.ts +17 -0
- package/lib/modules/Cart/types.d.ts +2 -0
- package/lib/modules/Cart/utils/cartProduct.js +39 -12
- package/lib/modules/Cart/utils/changePrice.js +9 -13
- package/lib/modules/Discount/index.d.ts +4 -13
- package/lib/modules/Discount/index.js +5 -76
- package/lib/modules/Discount/types.d.ts +18 -13
- package/lib/modules/Order/index.d.ts +1 -67
- package/lib/modules/Order/index.js +1 -525
- package/lib/modules/Order/types.d.ts +12 -176
- package/lib/modules/Order/utils.d.ts +0 -118
- package/lib/modules/Order/utils.js +2 -483
- package/lib/modules/Payment/index.d.ts +2 -1
- package/lib/modules/Payment/index.js +1 -0
- package/lib/modules/Payment/utils.js +3 -0
- package/lib/modules/Payment/walletpass.d.ts +23 -0
- package/lib/modules/Payment/walletpass.js +94 -17
- package/lib/modules/Product/utils.js +2 -2
- package/lib/modules/ProductList/index.d.ts +2 -4
- package/lib/modules/ProductList/index.js +39 -46
- package/lib/modules/Rules/index.d.ts +9 -5
- package/lib/modules/Rules/index.js +776 -292
- package/lib/modules/Rules/types.d.ts +2 -0
- package/lib/modules/Schedule/getDateIsInSchedule.js +11 -13
- package/lib/modules/Schedule/utils.d.ts +1 -1
- package/lib/modules/Summary/types.d.ts +2 -0
- package/lib/modules/Summary/utils.d.ts +9 -3
- package/lib/modules/Summary/utils.js +34 -45
- package/lib/modules/index.d.ts +0 -4
- package/lib/modules/index.js +1 -9
- package/lib/plugins/window.d.ts +2 -0
- package/lib/solution/BookingByStep/index.d.ts +3 -2
- package/lib/solution/BookingByStep/index.js +4 -6
- package/lib/solution/BookingByStep/types.d.ts +1 -3
- package/lib/solution/BookingByStep/types.js +0 -10
- package/lib/solution/BookingByStep/utils/timeslots.d.ts +1 -3
- package/lib/solution/BookingByStep/utils/timeslots.js +11 -19
- package/lib/solution/Checkout/index.js +2 -0
- package/lib/solution/ShopDiscount/index.d.ts +2 -3
- package/lib/solution/ShopDiscount/index.js +27 -22
- package/lib/solution/ShopDiscount/types.d.ts +1 -1
- package/lib/solution/ShopDiscount/utils.js +10 -6
- package/lib/solution/index.d.ts +0 -2
- package/lib/solution/index.js +1 -5
- package/package.json +2 -2
- package/dist/apis/picoding.d.ts +0 -0
- package/dist/apis/picoding.js +0 -1
- package/dist/model/strategy/adapter/dataVariant/adapter.d.ts +0 -50
- package/dist/model/strategy/adapter/dataVariant/adapter.js +0 -167
- package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +0 -89
- package/dist/model/strategy/adapter/dataVariant/evaluator.js +0 -867
- package/dist/model/strategy/adapter/dataVariant/examples.d.ts +0 -39
- package/dist/model/strategy/adapter/dataVariant/examples.js +0 -277
- package/dist/model/strategy/adapter/dataVariant/index.d.ts +0 -4
- package/dist/model/strategy/adapter/dataVariant/index.js +0 -4
- package/dist/model/strategy/adapter/dataVariant/type.d.ts +0 -149
- package/dist/model/strategy/adapter/dataVariant/type.js +0 -54
- package/dist/modules/OpenData/index.d.ts +0 -24
- package/dist/modules/OpenData/index.js +0 -173
- package/dist/modules/OpenData/types.d.ts +0 -73
- package/dist/modules/OpenData/types.js +0 -1
- package/dist/modules/OpenData/utils.d.ts +0 -2
- package/dist/modules/OpenData/utils.js +0 -75
- package/dist/modules/Quotation/index.d.ts +0 -48
- package/dist/modules/Quotation/index.js +0 -248
- package/dist/modules/Quotation/types.d.ts +0 -42
- package/dist/modules/Quotation/types.js +0 -1
- package/dist/modules/SalesSummary/index.d.ts +0 -63
- package/dist/modules/SalesSummary/index.js +0 -174
- package/dist/modules/SalesSummary/types.d.ts +0 -60
- package/dist/modules/SalesSummary/types.js +0 -1
- package/dist/modules/SalesSummary/utils.d.ts +0 -30
- package/dist/modules/SalesSummary/utils.js +0 -480
- package/dist/modules/ScanOrderLogger/index.d.ts +0 -23
- package/dist/modules/ScanOrderLogger/index.js +0 -174
- package/dist/modules/ScanOrderLogger/providers/feishu.d.ts +0 -2
- package/dist/modules/ScanOrderLogger/providers/feishu.js +0 -221
- package/dist/modules/ScanOrderLogger/providers/grafana.d.ts +0 -2
- package/dist/modules/ScanOrderLogger/providers/grafana.js +0 -50
- package/dist/modules/ScanOrderLogger/types.d.ts +0 -53
- package/dist/modules/ScanOrderLogger/types.js +0 -1
- package/dist/solution/ScanOrder/index.d.ts +0 -158
- package/dist/solution/ScanOrder/index.js +0 -3474
- package/dist/solution/ScanOrder/types.d.ts +0 -306
- package/dist/solution/ScanOrder/types.js +0 -35
- package/dist/solution/ScanOrder/utils.d.ts +0 -172
- package/dist/solution/ScanOrder/utils.js +0 -796
- package/dist/solution/VenueBooking/index.d.ts +0 -252
- package/dist/solution/VenueBooking/index.js +0 -3769
- package/dist/solution/VenueBooking/sales-section-4-annotated.json +0 -343
- package/dist/solution/VenueBooking/types.d.ts +0 -156
- package/dist/solution/VenueBooking/types.js +0 -22
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts +0 -11
- package/dist/solution/VenueBooking/utils/dateSummary.js +0 -91
- package/dist/solution/VenueBooking/utils/resource.d.ts +0 -14
- package/dist/solution/VenueBooking/utils/resource.js +0 -131
- package/dist/solution/VenueBooking/utils/slotMerge.d.ts +0 -32
- package/dist/solution/VenueBooking/utils/slotMerge.js +0 -233
- package/dist/solution/VenueBooking/utils/smartPricing.d.ts +0 -71
- package/dist/solution/VenueBooking/utils/smartPricing.js +0 -302
- package/dist/solution/VenueBooking/utils/timeSlot.d.ts +0 -34
- package/dist/solution/VenueBooking/utils/timeSlot.js +0 -458
- package/dist/solution/VenueBooking/utils.d.ts +0 -1
- package/dist/solution/VenueBooking/utils.js +0 -1
- package/lib/apis/picoding.d.ts +0 -0
- package/lib/apis/picoding.js +0 -0
- package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +0 -50
- package/lib/model/strategy/adapter/dataVariant/adapter.js +0 -149
- package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +0 -89
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +0 -666
- package/lib/model/strategy/adapter/dataVariant/examples.d.ts +0 -39
- package/lib/model/strategy/adapter/dataVariant/examples.js +0 -293
- package/lib/model/strategy/adapter/dataVariant/index.d.ts +0 -4
- package/lib/model/strategy/adapter/dataVariant/index.js +0 -38
- package/lib/model/strategy/adapter/dataVariant/type.d.ts +0 -149
- package/lib/model/strategy/adapter/dataVariant/type.js +0 -31
- package/lib/modules/OpenData/index.d.ts +0 -24
- package/lib/modules/OpenData/index.js +0 -119
- package/lib/modules/OpenData/types.d.ts +0 -73
- package/lib/modules/OpenData/types.js +0 -17
- package/lib/modules/OpenData/utils.d.ts +0 -2
- package/lib/modules/OpenData/utils.js +0 -111
- package/lib/modules/Quotation/index.d.ts +0 -48
- package/lib/modules/Quotation/index.js +0 -152
- package/lib/modules/Quotation/types.d.ts +0 -42
- package/lib/modules/Quotation/types.js +0 -17
- package/lib/modules/SalesSummary/index.d.ts +0 -63
- package/lib/modules/SalesSummary/index.js +0 -105
- package/lib/modules/SalesSummary/types.d.ts +0 -60
- package/lib/modules/SalesSummary/types.js +0 -17
- package/lib/modules/SalesSummary/utils.d.ts +0 -30
- package/lib/modules/SalesSummary/utils.js +0 -420
- package/lib/modules/ScanOrderLogger/index.d.ts +0 -23
- package/lib/modules/ScanOrderLogger/index.js +0 -147
- package/lib/modules/ScanOrderLogger/providers/feishu.d.ts +0 -2
- package/lib/modules/ScanOrderLogger/providers/feishu.js +0 -157
- package/lib/modules/ScanOrderLogger/providers/grafana.d.ts +0 -2
- package/lib/modules/ScanOrderLogger/providers/grafana.js +0 -52
- package/lib/modules/ScanOrderLogger/types.d.ts +0 -53
- package/lib/modules/ScanOrderLogger/types.js +0 -17
- package/lib/solution/ScanOrder/index.d.ts +0 -158
- package/lib/solution/ScanOrder/index.js +0 -2135
- package/lib/solution/ScanOrder/types.d.ts +0 -306
- package/lib/solution/ScanOrder/types.js +0 -36
- package/lib/solution/ScanOrder/utils.d.ts +0 -172
- package/lib/solution/ScanOrder/utils.js +0 -658
- package/lib/solution/VenueBooking/index.d.ts +0 -252
- package/lib/solution/VenueBooking/index.js +0 -2204
- package/lib/solution/VenueBooking/sales-section-4-annotated.json +0 -343
- package/lib/solution/VenueBooking/types.d.ts +0 -156
- package/lib/solution/VenueBooking/types.js +0 -45
- package/lib/solution/VenueBooking/utils/dateSummary.d.ts +0 -11
- package/lib/solution/VenueBooking/utils/dateSummary.js +0 -105
- package/lib/solution/VenueBooking/utils/resource.d.ts +0 -14
- package/lib/solution/VenueBooking/utils/resource.js +0 -92
- package/lib/solution/VenueBooking/utils/slotMerge.d.ts +0 -32
- package/lib/solution/VenueBooking/utils/slotMerge.js +0 -236
- package/lib/solution/VenueBooking/utils/smartPricing.d.ts +0 -71
- package/lib/solution/VenueBooking/utils/smartPricing.js +0 -225
- package/lib/solution/VenueBooking/utils/timeSlot.d.ts +0 -34
- package/lib/solution/VenueBooking/utils/timeSlot.js +0 -343
- package/lib/solution/VenueBooking/utils.d.ts +0 -1
- package/lib/solution/VenueBooking/utils.js +0 -69
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export * from './types';
|
|
|
6
6
|
export * from './modules';
|
|
7
7
|
export * from './plugins';
|
|
8
8
|
export * from './solution';
|
|
9
|
+
export * from './model';
|
|
9
10
|
export { PisellOSCore } from './core';
|
|
10
|
-
export { DataVariantEvaluator } from './model/strategy/adapter/dataVariant/evaluator';
|
|
11
11
|
import PisellOSCore from './core';
|
|
12
12
|
export default PisellOSCore;
|
package/dist/index.js
CHANGED
|
@@ -8,13 +8,11 @@ export * from "./types";
|
|
|
8
8
|
export * from "./modules";
|
|
9
9
|
export * from "./plugins";
|
|
10
10
|
export * from "./solution";
|
|
11
|
+
export * from "./model";
|
|
11
12
|
|
|
12
13
|
// 导出核心实现
|
|
13
14
|
export { PisellOSCore } from "./core";
|
|
14
15
|
|
|
15
|
-
// 策略评估器(宿主注入 smart pricing / promotion 等场景使用)
|
|
16
|
-
export { DataVariantEvaluator } from "./model/strategy/adapter/dataVariant/evaluator";
|
|
17
|
-
|
|
18
16
|
// 导出框架主类
|
|
19
17
|
import PisellOSCore from "./core";
|
|
20
18
|
export default PisellOSCore;
|
|
@@ -5,7 +5,3 @@ export { PromotionEvaluator } from './promotion/evaluator';
|
|
|
5
5
|
export { PromotionAdapter } from './promotion/adapter';
|
|
6
6
|
export { ItemRuleEvaluator } from './itemRule/evaluator';
|
|
7
7
|
export { ItemRuleAdapter } from './itemRule/adapter';
|
|
8
|
-
export { DataVariantEvaluator } from './dataVariant/evaluator';
|
|
9
|
-
export { DataVariantAdapter } from './dataVariant/adapter';
|
|
10
|
-
export { runDataVariantDemo } from './dataVariant/examples';
|
|
11
|
-
export * from './dataVariant/type';
|
|
@@ -4,8 +4,4 @@ export { WalletPassEvaluator } from "./walletPass/evaluator";
|
|
|
4
4
|
export { PromotionEvaluator } from "./promotion/evaluator";
|
|
5
5
|
export { PromotionAdapter } from "./promotion/adapter";
|
|
6
6
|
export { ItemRuleEvaluator } from "./itemRule/evaluator";
|
|
7
|
-
export { ItemRuleAdapter } from "./itemRule/adapter";
|
|
8
|
-
export { DataVariantEvaluator } from "./dataVariant/evaluator";
|
|
9
|
-
export { DataVariantAdapter } from "./dataVariant/adapter";
|
|
10
|
-
export { runDataVariantDemo } from "./dataVariant/examples";
|
|
11
|
-
export * from "./dataVariant/type";
|
|
7
|
+
export { ItemRuleAdapter } from "./itemRule/adapter";
|
|
@@ -719,7 +719,8 @@ export var PromotionEvaluator = /*#__PURE__*/function () {
|
|
|
719
719
|
unitProducts.push({
|
|
720
720
|
product: product,
|
|
721
721
|
price: product.price,
|
|
722
|
-
productId: product.id
|
|
722
|
+
productId: product.id,
|
|
723
|
+
sourceAvailableQty: availableQty
|
|
723
724
|
});
|
|
724
725
|
}
|
|
725
726
|
}
|
|
@@ -736,8 +737,13 @@ export var PromotionEvaluator = /*#__PURE__*/function () {
|
|
|
736
737
|
};
|
|
737
738
|
}
|
|
738
739
|
|
|
739
|
-
// 2.
|
|
740
|
+
// 2. 排序:优先选择来源数量是 x 倍数的商品(可完整凑组不拆分),然后按价格从高到低
|
|
740
741
|
unitProducts.sort(function (a, b) {
|
|
742
|
+
// 优先级1:来源购物车项数量是 x 的倍数的排前面(这些商品可以完整凑组,避免拆分)
|
|
743
|
+
var aIsMultiple = a.sourceAvailableQty > 0 && a.sourceAvailableQty % x === 0 ? 1 : 0;
|
|
744
|
+
var bIsMultiple = b.sourceAvailableQty > 0 && b.sourceAvailableQty % x === 0 ? 1 : 0;
|
|
745
|
+
if (aIsMultiple !== bIsMultiple) return bIsMultiple - aIsMultiple;
|
|
746
|
+
// 优先级2:按价格从高到低(优先使用高价商品)
|
|
741
747
|
return b.price - a.price;
|
|
742
748
|
});
|
|
743
749
|
|
|
@@ -833,7 +839,10 @@ export var PromotionEvaluator = /*#__PURE__*/function () {
|
|
|
833
839
|
var totalAllocated = allocatedPrices.reduce(function (sum, p) {
|
|
834
840
|
return sum.plus(p);
|
|
835
841
|
}, new Decimal(0));
|
|
836
|
-
|
|
842
|
+
// 取促销价和原价的最小值,避免促销反而加价
|
|
843
|
+
var productOriginalAmount = new Decimal(_product.price).mul(promoQty);
|
|
844
|
+
var actualTotal = Decimal.min(totalAllocated, productOriginalAmount);
|
|
845
|
+
var finalPricePerUnit = this.formatPrice(actualTotal.div(promoQty));
|
|
837
846
|
result.push(_objectSpread(_objectSpread({}, _product), {}, {
|
|
838
847
|
quantity: promoQty,
|
|
839
848
|
finalPrice: finalPricePerUnit,
|
|
@@ -843,9 +852,8 @@ export var PromotionEvaluator = /*#__PURE__*/function () {
|
|
|
843
852
|
isSplit: false,
|
|
844
853
|
matchedBundleIndex: matchedBundleIndex
|
|
845
854
|
}));
|
|
846
|
-
var productOriginalAmount = new Decimal(_product.price).mul(promoQty);
|
|
847
855
|
originalAmount = originalAmount.plus(productOriginalAmount);
|
|
848
|
-
finalAmount = finalAmount.plus(
|
|
856
|
+
finalAmount = finalAmount.plus(actualTotal);
|
|
849
857
|
} else if (promoQty === 0 && remainingQty > 0) {
|
|
850
858
|
// 全部不参与促销:保留原 id,finalPrice = 原价
|
|
851
859
|
result.push(_objectSpread(_objectSpread({}, _product), {}, {
|
|
@@ -865,7 +873,10 @@ export var PromotionEvaluator = /*#__PURE__*/function () {
|
|
|
865
873
|
var _totalAllocated = allocatedPrices.reduce(function (sum, p) {
|
|
866
874
|
return sum.plus(p);
|
|
867
875
|
}, new Decimal(0));
|
|
868
|
-
|
|
876
|
+
// 取促销价和原价的最小值,避免促销反而加价
|
|
877
|
+
var promoOriginalAmount = new Decimal(_product.price).mul(promoQty);
|
|
878
|
+
var _actualTotal = Decimal.min(_totalAllocated, promoOriginalAmount);
|
|
879
|
+
var _finalPricePerUnit = this.formatPrice(_actualTotal.div(promoQty));
|
|
869
880
|
result.push(_objectSpread(_objectSpread({}, _product), {}, {
|
|
870
881
|
id: this.generateRandomId(),
|
|
871
882
|
originalId: _product.id,
|
|
@@ -877,9 +888,8 @@ export var PromotionEvaluator = /*#__PURE__*/function () {
|
|
|
877
888
|
matchedBundleIndex: matchedBundleIndex,
|
|
878
889
|
isSplit: true
|
|
879
890
|
}));
|
|
880
|
-
var promoOriginalAmount = new Decimal(_product.price).mul(promoQty);
|
|
881
891
|
originalAmount = originalAmount.plus(promoOriginalAmount);
|
|
882
|
-
finalAmount = finalAmount.plus(
|
|
892
|
+
finalAmount = finalAmount.plus(_actualTotal);
|
|
883
893
|
|
|
884
894
|
// 不参与促销的部分:保留原 id
|
|
885
895
|
result.push(_objectSpread(_objectSpread({}, _product), {}, {
|
|
@@ -898,11 +908,74 @@ export var PromotionEvaluator = /*#__PURE__*/function () {
|
|
|
898
908
|
// 更新已处理数量
|
|
899
909
|
processedQuantityMap.set(_key, _processedQty + _availableQty);
|
|
900
910
|
}
|
|
911
|
+
|
|
912
|
+
// 8. 尾差调整:确保促销商品的 finalPrice × quantity 之和精确等于 groupPrice × groupCount
|
|
901
913
|
} catch (err) {
|
|
902
914
|
_iterator13.e(err);
|
|
903
915
|
} finally {
|
|
904
916
|
_iterator13.f();
|
|
905
917
|
}
|
|
918
|
+
if (groupCount > 0) {
|
|
919
|
+
var expectedPromoTotal = new Decimal(groupPrice).mul(groupCount);
|
|
920
|
+
var promoItems = result.filter(function (p) {
|
|
921
|
+
return p.inPromotion;
|
|
922
|
+
});
|
|
923
|
+
var actualPromoTotal = new Decimal(0);
|
|
924
|
+
var _iterator14 = _createForOfIteratorHelper(promoItems),
|
|
925
|
+
_step14;
|
|
926
|
+
try {
|
|
927
|
+
for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
|
|
928
|
+
var _p = _step14.value;
|
|
929
|
+
actualPromoTotal = actualPromoTotal.plus(new Decimal(_p.finalPrice).mul(_p.quantity));
|
|
930
|
+
}
|
|
931
|
+
} catch (err) {
|
|
932
|
+
_iterator14.e(err);
|
|
933
|
+
} finally {
|
|
934
|
+
_iterator14.f();
|
|
935
|
+
}
|
|
936
|
+
var roundingDiff = actualPromoTotal.minus(expectedPromoTotal);
|
|
937
|
+
if (!roundingDiff.eq(0)) {
|
|
938
|
+
// 优先找 quantity=1 的促销商品调整(差额直接加减到单价上)
|
|
939
|
+
var adjustTarget = promoItems.find(function (p) {
|
|
940
|
+
return p.quantity === 1;
|
|
941
|
+
});
|
|
942
|
+
if (adjustTarget) {
|
|
943
|
+
adjustTarget.finalPrice = this.formatPrice(new Decimal(adjustTarget.finalPrice).minus(roundingDiff));
|
|
944
|
+
} else if (promoItems.length > 0) {
|
|
945
|
+
// 没有 quantity=1 的促销商品,从最后一个促销商品中拆出1件做尾差调整
|
|
946
|
+
var lastPromo = promoItems[promoItems.length - 1];
|
|
947
|
+
var adjustedUnitPrice = this.formatPrice(new Decimal(lastPromo.finalPrice).minus(roundingDiff));
|
|
948
|
+
|
|
949
|
+
// 原商品减少1件
|
|
950
|
+
lastPromo.quantity -= 1;
|
|
951
|
+
lastPromo.isSplit = true;
|
|
952
|
+
|
|
953
|
+
// 拆出1件用调整后的价格
|
|
954
|
+
result.push(_objectSpread(_objectSpread({}, lastPromo), {}, {
|
|
955
|
+
id: this.generateRandomId(),
|
|
956
|
+
originalId: lastPromo.originalId || lastPromo.id,
|
|
957
|
+
quantity: 1,
|
|
958
|
+
finalPrice: adjustedUnitPrice,
|
|
959
|
+
isSplit: true
|
|
960
|
+
}));
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
// 重新计算 finalAmount
|
|
964
|
+
finalAmount = new Decimal(0);
|
|
965
|
+
var _iterator15 = _createForOfIteratorHelper(result),
|
|
966
|
+
_step15;
|
|
967
|
+
try {
|
|
968
|
+
for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
|
|
969
|
+
var p = _step15.value;
|
|
970
|
+
finalAmount = finalAmount.plus(new Decimal(p.finalPrice).mul(p.quantity));
|
|
971
|
+
}
|
|
972
|
+
} catch (err) {
|
|
973
|
+
_iterator15.e(err);
|
|
974
|
+
} finally {
|
|
975
|
+
_iterator15.f();
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
}
|
|
906
979
|
return {
|
|
907
980
|
products: result,
|
|
908
981
|
originalAmount: originalAmount.toNumber(),
|
|
@@ -937,11 +1010,11 @@ export var PromotionEvaluator = /*#__PURE__*/function () {
|
|
|
937
1010
|
// 对于 bundle 子商品匹配,促销数量 = 主商品数量 × bundle子商品数量
|
|
938
1011
|
var totalPromoQty = 0;
|
|
939
1012
|
var productInfoMap = new Map();
|
|
940
|
-
var
|
|
941
|
-
|
|
1013
|
+
var _iterator16 = _createForOfIteratorHelper(groupProducts),
|
|
1014
|
+
_step16;
|
|
942
1015
|
try {
|
|
943
|
-
for (
|
|
944
|
-
var product =
|
|
1016
|
+
for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
|
|
1017
|
+
var product = _step16.value;
|
|
945
1018
|
var key = this.getProductKey(product);
|
|
946
1019
|
var processedQty = processedQuantityMap.get(key) || 0;
|
|
947
1020
|
var availableQty = product.quantity - processedQty;
|
|
@@ -967,18 +1040,18 @@ export var PromotionEvaluator = /*#__PURE__*/function () {
|
|
|
967
1040
|
|
|
968
1041
|
// 2. 判断是否满足促销条件
|
|
969
1042
|
} catch (err) {
|
|
970
|
-
|
|
1043
|
+
_iterator16.e(err);
|
|
971
1044
|
} finally {
|
|
972
|
-
|
|
1045
|
+
_iterator16.f();
|
|
973
1046
|
}
|
|
974
1047
|
var isFulfilled = totalPromoQty >= buyQuantity;
|
|
975
1048
|
|
|
976
1049
|
// 3. 生成商品结果(第二次遍历)
|
|
977
|
-
var
|
|
978
|
-
|
|
1050
|
+
var _iterator17 = _createForOfIteratorHelper(groupProducts),
|
|
1051
|
+
_step17;
|
|
979
1052
|
try {
|
|
980
|
-
for (
|
|
981
|
-
var _product2 =
|
|
1053
|
+
for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {
|
|
1054
|
+
var _product2 = _step17.value;
|
|
982
1055
|
var _key2 = this.getProductKey(_product2);
|
|
983
1056
|
var info = productInfoMap.get(_key2);
|
|
984
1057
|
if (!info || info.availableQty <= 0) continue;
|
|
@@ -1006,9 +1079,9 @@ export var PromotionEvaluator = /*#__PURE__*/function () {
|
|
|
1006
1079
|
|
|
1007
1080
|
// 4. 计算赠品数量(使用促销数量)
|
|
1008
1081
|
} catch (err) {
|
|
1009
|
-
|
|
1082
|
+
_iterator17.e(err);
|
|
1010
1083
|
} finally {
|
|
1011
|
-
|
|
1084
|
+
_iterator17.f();
|
|
1012
1085
|
}
|
|
1013
1086
|
var giftCount = 0;
|
|
1014
1087
|
if (isFulfilled) {
|
|
@@ -1037,11 +1110,11 @@ export var PromotionEvaluator = /*#__PURE__*/function () {
|
|
|
1037
1110
|
key: "getRemainingProducts",
|
|
1038
1111
|
value: function getRemainingProducts(allProducts, processedQuantityMap) {
|
|
1039
1112
|
var result = [];
|
|
1040
|
-
var
|
|
1041
|
-
|
|
1113
|
+
var _iterator18 = _createForOfIteratorHelper(allProducts),
|
|
1114
|
+
_step18;
|
|
1042
1115
|
try {
|
|
1043
|
-
for (
|
|
1044
|
-
var product =
|
|
1116
|
+
for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {
|
|
1117
|
+
var product = _step18.value;
|
|
1045
1118
|
var key = this.getProductKey(product);
|
|
1046
1119
|
var processedQty = processedQuantityMap.get(key) || 0;
|
|
1047
1120
|
var remainingQty = product.quantity - processedQty;
|
|
@@ -1056,9 +1129,9 @@ export var PromotionEvaluator = /*#__PURE__*/function () {
|
|
|
1056
1129
|
}
|
|
1057
1130
|
}
|
|
1058
1131
|
} catch (err) {
|
|
1059
|
-
|
|
1132
|
+
_iterator18.e(err);
|
|
1060
1133
|
} finally {
|
|
1061
|
-
|
|
1134
|
+
_iterator18.f();
|
|
1062
1135
|
}
|
|
1063
1136
|
return result;
|
|
1064
1137
|
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
// 导出评估器
|
|
2
|
-
export { PromotionEvaluator } from "./evaluator";
|
|
3
|
-
|
|
4
|
-
// 导出适配器
|
|
5
|
-
export { PromotionAdapter } from "./adapter";
|
|
6
|
-
export { default } from "./adapter";
|
|
7
|
-
|
|
8
|
-
// 导出策略配置示例常量
|
|
9
|
-
export { X_ITEMS_FOR_Y_PRICE_STRATEGY, BUY_X_GET_Y_FREE_STRATEGY } from "./examples";
|
|
@@ -8,10 +8,12 @@ export declare class WalletPassEvaluator {
|
|
|
8
8
|
private engine;
|
|
9
9
|
private strategyConfigs;
|
|
10
10
|
private locale;
|
|
11
|
+
private otherParams;
|
|
11
12
|
constructor();
|
|
12
13
|
setStrategyConfigs(strategyConfigs: StrategyConfig[]): void;
|
|
13
14
|
getStrategyConfigs(): StrategyConfig[];
|
|
14
15
|
setLocale(locale: string): void;
|
|
16
|
+
setOtherParams(otherParams: any): void;
|
|
15
17
|
getText(key: string): string;
|
|
16
18
|
/**
|
|
17
19
|
* 搜索券的格式
|
|
@@ -24,6 +24,43 @@ var defaultStrategyMetadataCustom = {
|
|
|
24
24
|
deductOptionPrice: false
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* 条件 field → reasonCode 映射
|
|
29
|
+
* 用于将策略引擎返回的 failedField 转换为本地化文案 key
|
|
30
|
+
*/
|
|
31
|
+
var FIELD_REASON_CODE_MAP = {
|
|
32
|
+
orderTotalAmount: 'order_total_amount_not_enough',
|
|
33
|
+
applicableProductTotalAmount: 'applicable_product_total_amount_not_enough',
|
|
34
|
+
applicableProductCount: 'applicable_product_count_not_enough'
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 金额类型 field 集合(需要在文案前拼货币符号)
|
|
39
|
+
*/
|
|
40
|
+
var AMOUNT_FIELDS = new Set(['orderTotalAmount', 'applicableProductTotalAmount']);
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 用阈值与货币符号替换文案中的占位符
|
|
44
|
+
* 支持占位符:{value} / ${value} / {currency}
|
|
45
|
+
*/
|
|
46
|
+
function formatReason(template, value) {
|
|
47
|
+
var currency = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
|
|
48
|
+
if (!template) return template;
|
|
49
|
+
var v = value === undefined || value === null ? '' : String(value);
|
|
50
|
+
var c = currency === undefined || currency === null ? '' : String(currency);
|
|
51
|
+
// 注意:必须先替换 value,再替换 currency
|
|
52
|
+
// 否则 currency 注入的 "$" 会被后续的 /\$\{value\}/ 正则误吞
|
|
53
|
+
// 使用函数作为替换参数,避免替换串中的 "$" 被 String.prototype.replace
|
|
54
|
+
// 当作特殊序列(如 $$ -> $、$& 等)处理
|
|
55
|
+
return template.replace(/\$\{value\}/g, function () {
|
|
56
|
+
return v;
|
|
57
|
+
}).replace(/\{value\}/g, function () {
|
|
58
|
+
return v;
|
|
59
|
+
}).replace(/\{currency\}/g, function () {
|
|
60
|
+
return c;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
27
64
|
/**
|
|
28
65
|
* Wallet Pass 评估器
|
|
29
66
|
* 用于评估哪些 voucher 可以在当前订单中使用
|
|
@@ -34,6 +71,7 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
|
|
|
34
71
|
_defineProperty(this, "engine", void 0);
|
|
35
72
|
_defineProperty(this, "strategyConfigs", []);
|
|
36
73
|
_defineProperty(this, "locale", 'en');
|
|
74
|
+
_defineProperty(this, "otherParams", {});
|
|
37
75
|
this.engine = new StrategyEngine({
|
|
38
76
|
debug: false,
|
|
39
77
|
enableTrace: false
|
|
@@ -57,6 +95,11 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
|
|
|
57
95
|
value: function setLocale(locale) {
|
|
58
96
|
this.locale = locale;
|
|
59
97
|
}
|
|
98
|
+
}, {
|
|
99
|
+
key: "setOtherParams",
|
|
100
|
+
value: function setOtherParams(otherParams) {
|
|
101
|
+
this.otherParams = otherParams;
|
|
102
|
+
}
|
|
60
103
|
}, {
|
|
61
104
|
key: "getText",
|
|
62
105
|
value: function getText(key) {
|
|
@@ -191,13 +234,17 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
|
|
|
191
234
|
strategyResult: evaluationResult
|
|
192
235
|
});
|
|
193
236
|
} else {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
237
|
+
var _evaluationResult$mat, _evaluationResult$mat2, _this$otherParams, _this$otherParams$get, _this$otherParams2;
|
|
238
|
+
// 优先根据失败的 field 映射到具体的 reasonCode(更精确的失败原因)
|
|
239
|
+
var reasonCode = 'not_meet_the_required_conditions';
|
|
240
|
+
var thresholdValue = undefined;
|
|
241
|
+
var failedField = (_evaluationResult$mat = evaluationResult.matched) === null || _evaluationResult$mat === void 0 ? void 0 : _evaluationResult$mat.failedField;
|
|
242
|
+
var failedRule = (_evaluationResult$mat2 = evaluationResult.matched) === null || _evaluationResult$mat2 === void 0 || (_evaluationResult$mat2 = _evaluationResult$mat2.failedRules) === null || _evaluationResult$mat2 === void 0 ? void 0 : _evaluationResult$mat2[0];
|
|
243
|
+
if (failedField && FIELD_REASON_CODE_MAP[failedField]) {
|
|
244
|
+
reasonCode = FIELD_REASON_CODE_MAP[failedField];
|
|
245
|
+
thresholdValue = failedRule === null || failedRule === void 0 ? void 0 : failedRule.value;
|
|
246
|
+
} else if (evaluationResult.code) {
|
|
247
|
+
// 兜底:保留原有 code → reasonCode 映射
|
|
201
248
|
var codeMapping = {
|
|
202
249
|
INSUFFICIENT_AMOUNT: 'not_meet_the_required_conditions',
|
|
203
250
|
USAGE_LIMIT_EXCEEDED: 'usage_limit_reached',
|
|
@@ -207,6 +254,11 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
|
|
|
207
254
|
};
|
|
208
255
|
reasonCode = codeMapping[evaluationResult.code] || 'not_meet_the_required_conditions';
|
|
209
256
|
}
|
|
257
|
+
var rawText = this.getText(reasonCode);
|
|
258
|
+
// 金额类型字段:从 otherParams.getData 取货币符号;非金额或取不到则留空
|
|
259
|
+
var currency = failedField && AMOUNT_FIELDS.has(failedField) ? ((_this$otherParams = this.otherParams) === null || _this$otherParams === void 0 || (_this$otherParams$get = (_this$otherParams2 = _this$otherParams).getData) === null || _this$otherParams$get === void 0 ? void 0 : _this$otherParams$get.call(_this$otherParams2, 'shop_symbol')) || '' : '';
|
|
260
|
+
console.log(currency, 'currency12345');
|
|
261
|
+
var reason = thresholdValue !== undefined ? formatReason(rawText, thresholdValue, currency) : rawText;
|
|
210
262
|
results.push({
|
|
211
263
|
voucher: voucher,
|
|
212
264
|
isApplicable: false,
|
|
@@ -214,7 +266,7 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
|
|
|
214
266
|
maxDeduction: 0,
|
|
215
267
|
deductTaxAndFee: false,
|
|
216
268
|
applicableProductIds: [],
|
|
217
|
-
reason:
|
|
269
|
+
reason: reason,
|
|
218
270
|
reasonCode: reasonCode,
|
|
219
271
|
strategyResult: evaluationResult
|
|
220
272
|
});
|
|
@@ -454,6 +506,7 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
|
|
|
454
506
|
}, {
|
|
455
507
|
key: "calculateApplicableProducts",
|
|
456
508
|
value: function calculateApplicableProducts(products, applicableProductIds, deductTaxAndFee) {
|
|
509
|
+
console.log(products, 'products1234');
|
|
457
510
|
var total = 0;
|
|
458
511
|
var count = 0;
|
|
459
512
|
|
|
@@ -5,7 +5,10 @@ export var locales = {
|
|
|
5
5
|
'usage_limit_reached': '已达到使用次数上限',
|
|
6
6
|
'max_passes_per_item_reached': '该商品已达到卡券使用上限',
|
|
7
7
|
'not_available_for_this_channel': '当前渠道不可使用',
|
|
8
|
-
'not_valid_for_this_order_type': '当前订单类型不适用'
|
|
8
|
+
'not_valid_for_this_order_type': '当前订单类型不适用',
|
|
9
|
+
'order_total_amount_not_enough': '满 {currency}{value} 可用',
|
|
10
|
+
'applicable_product_total_amount_not_enough': '满 {currency}{value} 可用',
|
|
11
|
+
'applicable_product_count_not_enough': '至少 {value} 件'
|
|
9
12
|
},
|
|
10
13
|
'en': {
|
|
11
14
|
'not_meet_the_required_conditions': 'Not meet the required conditions.',
|
|
@@ -13,7 +16,10 @@ export var locales = {
|
|
|
13
16
|
'usage_limit_reached': 'Usage limit reached.',
|
|
14
17
|
'max_passes_per_item_reached': 'Max passes per item reached.',
|
|
15
18
|
'not_available_for_this_channel': 'Not available for this channel.',
|
|
16
|
-
'not_valid_for_this_order_type': 'Not valid for this order type.'
|
|
19
|
+
'not_valid_for_this_order_type': 'Not valid for this order type.',
|
|
20
|
+
'order_total_amount_not_enough': 'Spend {currency}{value} to use',
|
|
21
|
+
'applicable_product_total_amount_not_enough': 'Spend {currency}{value} to use',
|
|
22
|
+
'applicable_product_count_not_enough': 'Min. Qty {value}'
|
|
17
23
|
},
|
|
18
24
|
'zh-HK': {
|
|
19
25
|
'not_meet_the_required_conditions': '未達使用條件',
|
|
@@ -21,6 +27,9 @@ export var locales = {
|
|
|
21
27
|
'usage_limit_reached': '已達使用次數上限',
|
|
22
28
|
'max_passes_per_item_reached': '該商品已達卡券使用上限',
|
|
23
29
|
'not_available_for_this_channel': '當前渠道不可使用',
|
|
24
|
-
'not_valid_for_this_order_type': '當前訂單類型不適用'
|
|
30
|
+
'not_valid_for_this_order_type': '當前訂單類型不適用',
|
|
31
|
+
'order_total_amount_not_enough': '滿 {currency}{value} 可用',
|
|
32
|
+
'applicable_product_total_amount_not_enough': '滿 {currency}{value} 可用',
|
|
33
|
+
'applicable_product_count_not_enough': '至少 {value} 件'
|
|
25
34
|
}
|
|
26
35
|
};
|
|
@@ -27,17 +27,30 @@ export declare class StrategyEngine {
|
|
|
27
27
|
*
|
|
28
28
|
* @param group 条件组
|
|
29
29
|
* @param context 运行时上下文
|
|
30
|
-
* @returns
|
|
30
|
+
* @returns 评估结果对象,包含条件是否满足、收集到的 actionIds、以及失败的原子规则信息
|
|
31
31
|
*/
|
|
32
32
|
private evaluateConditionGroup;
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
34
|
+
* 评估条件组的逻辑运算(带失败规则收集)
|
|
35
|
+
*
|
|
36
|
+
* 失败规则收集策略:
|
|
37
|
+
* - `and`:返回第一个失败的原子规则(嵌套 group 递归取其首个失败原子规则)
|
|
38
|
+
* - `or`:所有分支失败时,聚合每个分支的失败规则
|
|
39
|
+
* - `not`:被取反规则实际通过时,记录该规则
|
|
40
|
+
*/
|
|
41
|
+
private evaluateGroupLogicDetailed;
|
|
42
|
+
/**
|
|
43
|
+
* 评估单个规则(带失败规则收集)
|
|
44
|
+
*/
|
|
45
|
+
private evaluateRuleDetailed;
|
|
46
|
+
/**
|
|
47
|
+
* 评估原子规则(不收集失败信息,仅返回布尔结果)
|
|
35
48
|
*/
|
|
36
|
-
private
|
|
49
|
+
private evaluateAtomicRule;
|
|
37
50
|
/**
|
|
38
|
-
*
|
|
51
|
+
* 构建失败规则信息
|
|
39
52
|
*/
|
|
40
|
-
private
|
|
53
|
+
private buildFailedRuleInfo;
|
|
41
54
|
/**
|
|
42
55
|
* 评估代码模式条件
|
|
43
56
|
*/
|