@pisell/pisellos 0.10.14 → 0.10.16
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/core/index.js +6 -9
- package/dist/model/strategy/adapter/walletPass/example.js +3 -26
- package/dist/model/strategy/strategy-example.js +5 -19
- package/dist/modules/Cart/index.js +0 -3
- package/dist/modules/Cart/utils/cartProduct.js +0 -1
- package/dist/modules/Date/index.js +1 -5
- package/dist/modules/Discount/index.js +2 -4
- package/dist/modules/OpenData/index.js +0 -2
- package/dist/modules/Order/index.d.ts +1 -1
- package/dist/modules/Order/index.js +75 -91
- package/dist/modules/Order/types.d.ts +5 -1
- package/dist/modules/Order/utils/virtualSettlement.d.ts +8 -1
- package/dist/modules/Order/utils/virtualSettlement.js +15 -2
- package/dist/modules/Order/utils.js +7 -1
- package/dist/modules/Payment/index.js +97 -162
- package/dist/modules/Product/types.d.ts +2 -0
- package/dist/modules/Rules/index.js +1 -4
- package/dist/modules/Schedule/index.js +0 -1
- package/dist/modules/Schedule/utils.js +0 -1
- package/dist/modules/Step/index.js +0 -1
- package/dist/plugins/request.js +1 -4
- package/dist/plugins/window.js +2 -6
- package/dist/server/index.js +97 -129
- package/dist/server/modules/menu/index.js +32 -41
- package/dist/server/modules/order/index.js +2 -4
- package/dist/server/modules/products/index.js +24 -42
- package/dist/server/modules/quotation/index.js +29 -38
- package/dist/server/modules/resource/index.js +3 -4
- package/dist/server/modules/schedule/index.js +27 -35
- package/dist/server/utils/product.js +0 -1
- package/dist/solution/BaseSales/index.js +107 -76
- package/dist/solution/BaseSales/types.d.ts +2 -0
- package/dist/solution/BaseSales/utils/cartPromotion.d.ts +5 -0
- package/dist/solution/BaseSales/utils/cartPromotion.js +15 -6
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +3 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +7 -1
- package/dist/solution/BaseSales/utils.js +6 -3
- package/dist/solution/BookingByStep/index.d.ts +2 -2
- package/dist/solution/BookingByStep/index.js +7 -59
- package/dist/solution/BookingByStep/utils/capacity.js +1 -11
- package/dist/solution/BookingByStep/utils/resources.js +1 -3
- package/dist/solution/BookingByStep/utils/timeslots.js +2 -43
- package/dist/solution/BookingTicket/index.js +8 -4
- package/dist/solution/BookingTicket/utils/addProductDecision.js +3 -1
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +6 -7
- package/dist/solution/BookingTicket/utils/scan/handleScan.js +25 -31
- package/dist/solution/BookingTicket/utils/scan/index.js +6 -10
- package/dist/solution/BuyTickets/index.js +9 -12
- package/dist/solution/Checkout/index.js +177 -252
- package/dist/solution/Checkout/utils/index.js +4 -16
- package/dist/solution/RegisterAndLogin/index.js +30 -76
- package/dist/solution/ScanOrder/index.js +50 -60
- package/dist/solution/ScanOrder/types.d.ts +2 -0
- package/dist/solution/ScanOrder/utils.js +6 -3
- package/dist/solution/ShopDiscount/index.js +2 -7
- package/dist/solution/VenueBooking/index.js +45 -55
- package/dist/utils/task.js +15 -18
- package/dist/utils/watch.js +0 -1
- package/lib/apis/picoding.js +2 -0
- package/lib/core/index.js +131 -131
- package/lib/effects/index.js +46 -57
- package/lib/index.js +82 -49
- package/lib/model/index.js +14 -21
- package/lib/model/strategy/adapter/dataVariant/adapter.js +38 -50
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +209 -315
- package/lib/model/strategy/adapter/dataVariant/examples.js +229 -237
- package/lib/model/strategy/adapter/dataVariant/index.js +39 -34
- package/lib/model/strategy/adapter/dataVariant/type.js +57 -28
- package/lib/model/strategy/adapter/index.js +100 -64
- package/lib/model/strategy/adapter/itemRule/adapter.js +156 -144
- package/lib/model/strategy/adapter/itemRule/evaluator.js +36 -48
- package/lib/model/strategy/adapter/itemRule/examples.js +295 -225
- package/lib/model/strategy/adapter/itemRule/index.js +83 -57
- package/lib/model/strategy/adapter/itemRule/type.js +97 -36
- package/lib/model/strategy/adapter/promotion/adapter.js +91 -69
- package/lib/model/strategy/adapter/promotion/evaluator.js +444 -310
- package/lib/model/strategy/adapter/promotion/examples.js +222 -234
- package/lib/model/strategy/adapter/promotion/index.js +43 -48
- package/lib/model/strategy/adapter/promotion/type.js +243 -36
- package/lib/model/strategy/adapter/type.js +4 -16
- package/lib/model/strategy/adapter/walletPass/evaluator.js +180 -150
- package/lib/model/strategy/adapter/walletPass/example.js +217 -190
- package/lib/model/strategy/adapter/walletPass/index.js +75 -51
- package/lib/model/strategy/adapter/walletPass/locales.js +36 -58
- package/lib/model/strategy/adapter/walletPass/type.js +4 -16
- package/lib/model/strategy/adapter/walletPass/utils.js +588 -378
- package/lib/model/strategy/engine.js +270 -168
- package/lib/model/strategy/index.js +49 -34
- package/lib/model/strategy/strategy-example.js +243 -239
- package/lib/model/strategy/type.js +100 -40
- package/lib/modules/Account/index.js +39 -53
- package/lib/modules/Account/types.js +20 -33
- package/lib/modules/AccountList/index.js +116 -154
- package/lib/modules/AccountList/types.js +30 -31
- package/lib/modules/AccountList/utils.js +18 -30
- package/lib/modules/BaseModule.js +23 -42
- package/lib/modules/BookingContext/index.js +158 -136
- package/lib/modules/BookingContext/types.js +46 -32
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +138 -146
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +78 -83
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +170 -150
- package/lib/modules/BookingContext/utils/flexible.js +38 -55
- package/lib/modules/BookingContext/utils/formatResourceList.js +19 -34
- package/lib/modules/BookingContext/utils/index.js +124 -41
- package/lib/modules/BookingContext/utils/noResource.js +58 -70
- package/lib/modules/BookingContext/utils/orderLineDisplay.js +14 -41
- package/lib/modules/BookingContext/utils/productExtend.js +202 -155
- package/lib/modules/BookingContext/utils/resourceErrors.js +53 -53
- package/lib/modules/BookingContext/utils/resourceSelection.js +19 -41
- package/lib/modules/BookingContext/utils/resources.js +209 -167
- package/lib/modules/BookingContext/utils/serviceTimes.js +115 -116
- package/lib/modules/BookingContext/utils/timeSlices.js +76 -86
- package/lib/modules/Cart/index.js +170 -124
- package/lib/modules/Cart/types.js +46 -51
- package/lib/modules/Cart/utils/cartAccount.js +40 -39
- package/lib/modules/Cart/utils/cartDate.js +56 -61
- package/lib/modules/Cart/utils/cartDiscount.js +28 -33
- package/lib/modules/Cart/utils/cartNote.js +27 -32
- package/lib/modules/Cart/utils/cartProduct.js +321 -251
- package/lib/modules/Cart/utils/cartRelationForms.js +29 -35
- package/lib/modules/Cart/utils/cartResource.js +70 -78
- package/lib/modules/Cart/utils/changePrice.js +22 -50
- package/lib/modules/Cart/utils/index.js +106 -48
- package/lib/modules/Customer/constants.js +13 -34
- package/lib/modules/Customer/index.js +235 -172
- package/lib/modules/Customer/types.js +38 -35
- package/lib/modules/Date/index.js +116 -115
- package/lib/modules/Date/types.js +16 -28
- package/lib/modules/Date/utils.js +174 -123
- package/lib/modules/Discount/index.js +133 -143
- package/lib/modules/Discount/types.js +9 -31
- package/lib/modules/Guests/index.js +30 -56
- package/lib/modules/Guests/types.js +23 -33
- package/lib/modules/Holder/index.js +209 -189
- package/lib/modules/Holder/types.js +4 -16
- package/lib/modules/Holder/utils.js +20 -49
- package/lib/modules/OpenData/index.js +70 -76
- package/lib/modules/OpenData/types.js +4 -16
- package/lib/modules/OpenData/utils.js +44 -78
- package/lib/modules/Order/index.d.ts +1 -1
- package/lib/modules/Order/index.js +1810 -2238
- package/lib/modules/Order/payment-utils.js +77 -120
- package/lib/modules/Order/types.d.ts +5 -1
- package/lib/modules/Order/types.js +87 -35
- package/lib/modules/Order/utils/bundleDiscountHydration.js +41 -74
- package/lib/modules/Order/utils/discountProductLineIdentity.js +142 -100
- package/lib/modules/Order/utils/manualProductDiscount.js +124 -123
- package/lib/modules/Order/utils/orderCollectionIdentity.js +184 -244
- package/lib/modules/Order/utils/virtualSettlement.d.ts +8 -1
- package/lib/modules/Order/utils/virtualSettlement.js +126 -164
- package/lib/modules/Order/utils.js +834 -668
- package/lib/modules/Payment/cash.js +20 -33
- package/lib/modules/Payment/cashRecommendationAlgorithm.js +145 -76
- package/lib/modules/Payment/eftpos.js +16 -30
- package/lib/modules/Payment/index.js +532 -399
- package/lib/modules/Payment/mx51.js +1 -0
- package/lib/modules/Payment/types.js +230 -108
- package/lib/modules/Payment/utils.js +52 -51
- package/lib/modules/Payment/walletpass.js +485 -660
- package/lib/modules/Product/index.js +51 -46
- package/lib/modules/Product/types.d.ts +2 -0
- package/lib/modules/Product/types.js +4 -16
- package/lib/modules/Product/utils.js +32 -33
- package/lib/modules/ProductList/index.js +138 -161
- package/lib/modules/ProductList/types.js +9 -31
- package/lib/modules/Quotation/index.js +66 -100
- package/lib/modules/Quotation/types.js +4 -16
- package/lib/modules/Resource/index.js +27 -59
- package/lib/modules/Resource/types.js +22 -32
- package/lib/modules/Resource/utils.js +30 -38
- package/lib/modules/ResourcePlanner/index.js +25 -23
- package/lib/modules/ResourcePlanner/localClock.js +54 -119
- package/lib/modules/ResourcePlanner/planner.js +591 -772
- package/lib/modules/ResourcePlanner/types.js +10 -29
- package/lib/modules/Rules/index.js +1218 -959
- package/lib/modules/Rules/types.js +17 -40
- package/lib/modules/SalesSummary/index.js +78 -89
- package/lib/modules/SalesSummary/types.js +4 -16
- package/lib/modules/SalesSummary/utils.js +359 -442
- package/lib/modules/ScanOrderLogger/index.js +59 -79
- package/lib/modules/ScanOrderLogger/providers/feishu.js +54 -78
- package/lib/modules/ScanOrderLogger/providers/grafana.js +13 -36
- package/lib/modules/ScanOrderLogger/types.js +4 -16
- package/lib/modules/Schedule/getDateIsInSchedule.js +334 -163
- package/lib/modules/Schedule/index.js +100 -114
- package/lib/modules/Schedule/type.js +4 -16
- package/lib/modules/Schedule/types.js +4 -16
- package/lib/modules/Schedule/utils.js +433 -291
- package/lib/modules/Step/index.js +40 -52
- package/lib/modules/Step/tyeps.js +4 -16
- package/lib/modules/Summary/index.js +66 -71
- package/lib/modules/Summary/types.js +4 -16
- package/lib/modules/Summary/utils.js +773 -418
- package/lib/modules/SurchargeList/index.js +46 -60
- package/lib/modules/SurchargeList/types.js +4 -16
- package/lib/modules/index.js +245 -63
- package/lib/plugins/app.js +4 -16
- package/lib/plugins/index.js +36 -25
- package/lib/plugins/request.js +137 -126
- package/lib/plugins/shopStore.js +4 -16
- package/lib/plugins/user.js +4 -16
- package/lib/plugins/window.js +171 -179
- package/lib/server/index.js +3027 -2655
- package/lib/server/modules/floor-plan/index.js +102 -123
- package/lib/server/modules/floor-plan/types.js +15 -30
- package/lib/server/modules/index.js +106 -68
- package/lib/server/modules/menu/index.js +146 -122
- package/lib/server/modules/menu/types.js +18 -31
- package/lib/server/modules/order/index.js +758 -956
- package/lib/server/modules/order/types.js +122 -33
- package/lib/server/modules/order/utils/filterBookings.js +219 -194
- package/lib/server/modules/order/utils/filterOrders.js +118 -92
- package/lib/server/modules/payment/index.js +59 -83
- package/lib/server/modules/payment/types.js +4 -16
- package/lib/server/modules/products/index.js +575 -459
- package/lib/server/modules/products/types.js +44 -34
- package/lib/server/modules/quotation/index.js +137 -172
- package/lib/server/modules/quotation/types.js +21 -31
- package/lib/server/modules/resource/index.js +213 -184
- package/lib/server/modules/resource/types.js +42 -33
- package/lib/server/modules/schedule/index.js +135 -123
- package/lib/server/modules/schedule/types.js +14 -21
- package/lib/server/modules/schedule/utils.js +334 -163
- package/lib/server/types.js +4 -16
- package/lib/server/utils/index.js +25 -23
- package/lib/server/utils/product.js +196 -139
- package/lib/server/utils/schedule.js +34 -41
- package/lib/server/utils/small-ticket.js +479 -456
- package/lib/server/utils/time.js +40 -49
- package/lib/solution/BaseSales/index.js +1276 -1485
- package/lib/solution/BaseSales/types.d.ts +2 -0
- package/lib/solution/BaseSales/types.js +42 -38
- package/lib/solution/BaseSales/utils/cartPromotion.d.ts +5 -0
- package/lib/solution/BaseSales/utils/cartPromotion.js +652 -498
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +85 -105
- package/lib/solution/BaseSales/utils/quotationPrice.js +56 -114
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +3 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +138 -180
- package/lib/solution/BaseSales/utils.js +161 -143
- package/lib/solution/BookingByStep/index.d.ts +2 -2
- package/lib/solution/BookingByStep/index.js +1527 -1340
- package/lib/solution/BookingByStep/types.js +40 -99
- package/lib/solution/BookingByStep/utils/capacity.js +192 -160
- package/lib/solution/BookingByStep/utils/products.js +42 -52
- package/lib/solution/BookingByStep/utils/resources.js +527 -330
- package/lib/solution/BookingByStep/utils/stock.js +65 -44
- package/lib/solution/BookingByStep/utils/timeslots.js +129 -131
- package/lib/solution/BookingTicket/index.js +598 -514
- package/lib/solution/BookingTicket/types.js +99 -77
- package/lib/solution/BookingTicket/utils/addProductDecision.js +229 -190
- package/lib/solution/BookingTicket/utils/addTimeAvailability.js +58 -89
- package/lib/solution/BookingTicket/utils/bookingStatus.js +107 -78
- package/lib/solution/BookingTicket/utils/cartView.js +114 -99
- package/lib/solution/BookingTicket/utils/exampleData.js +185 -0
- package/lib/solution/BookingTicket/utils/orderCustomer.js +18 -41
- package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +219 -86
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +168 -116
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +79 -91
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +54 -41
- package/lib/solution/BookingTicket/utils/scan/handleScan.js +84 -81
- package/lib/solution/BookingTicket/utils/scan/index.js +98 -104
- package/lib/solution/BookingTicket/utils/scan/scanCache.js +90 -43
- package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +52 -64
- package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +56 -58
- package/lib/solution/BookingTicket/utils/weighingProductSku.js +34 -48
- package/lib/solution/BuyTickets/index.js +67 -70
- package/lib/solution/BuyTickets/types.js +22 -38
- package/lib/solution/Checkout/index.js +1451 -1158
- package/lib/solution/Checkout/types.js +91 -61
- package/lib/solution/Checkout/utils/index.js +228 -156
- package/lib/solution/PlaceOrder/index.js +55 -0
- package/lib/solution/RegisterAndLogin/config.js +493 -460
- package/lib/solution/RegisterAndLogin/index.js +633 -630
- package/lib/solution/RegisterAndLogin/types.js +189 -76
- package/lib/solution/RegisterAndLogin/utils.js +183 -125
- package/lib/solution/Sales/index.js +328 -324
- package/lib/solution/Sales/types.js +27 -33
- package/lib/solution/ScanOrder/index.js +822 -852
- package/lib/solution/ScanOrder/types.d.ts +2 -0
- package/lib/solution/ScanOrder/types.js +33 -34
- package/lib/solution/ScanOrder/utils.js +412 -374
- package/lib/solution/ShopDiscount/index.js +226 -232
- package/lib/solution/ShopDiscount/types.js +15 -37
- package/lib/solution/ShopDiscount/utils.js +300 -172
- package/lib/solution/UnifiedBookingSales/index.js +1052 -1213
- package/lib/solution/UnifiedBookingSales/remoteOccupancyCache.js +99 -159
- package/lib/solution/UnifiedBookingSales/types.js +10 -32
- package/lib/solution/VenueBooking/index.js +811 -879
- package/lib/solution/VenueBooking/types.js +19 -39
- package/lib/solution/VenueBooking/utils/dateSummary.js +27 -56
- package/lib/solution/VenueBooking/utils/resource.js +31 -54
- package/lib/solution/VenueBooking/utils/slotMerge.js +94 -107
- package/lib/solution/VenueBooking/utils/timeSlot.js +132 -132
- package/lib/solution/VenueBooking/utils.js +130 -67
- package/lib/solution/index.js +124 -41
- package/lib/store/createStore.js +32 -29
- package/lib/types/index.js +4 -16
- package/lib/utils/payment-number.js +26 -46
- package/lib/utils/task.js +36 -36
- package/lib/utils/watch.js +81 -47
- package/package.json +2 -1
|
@@ -1,36 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __export = (target, all) => {
|
|
6
|
-
for (var name in all)
|
|
7
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
-
};
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
1
|
+
"use strict";
|
|
18
2
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
__export(evaluator_exports, {
|
|
22
|
-
DataVariantEvaluator: () => DataVariantEvaluator,
|
|
23
|
-
default: () => evaluator_default
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
24
5
|
});
|
|
25
|
-
|
|
26
|
-
var
|
|
27
|
-
var
|
|
28
|
-
var
|
|
29
|
-
|
|
6
|
+
exports.default = exports.DataVariantEvaluator = void 0;
|
|
7
|
+
var _engine = require("../../engine");
|
|
8
|
+
var _getDateIsInSchedule = require("../../../../modules/Schedule/getDateIsInSchedule");
|
|
9
|
+
var _adapter = require("./adapter");
|
|
10
|
+
/**
|
|
11
|
+
* Data Variant 评估器。
|
|
12
|
+
*
|
|
13
|
+
* OS Server 商品路由开启时由 ProductsModule 调用;路由关闭时由 ProductList 在远端响应后调用。
|
|
14
|
+
*/
|
|
15
|
+
class DataVariantEvaluator {
|
|
16
|
+
adapter;
|
|
17
|
+
strategyConfigs = [];
|
|
30
18
|
constructor() {
|
|
31
|
-
this.
|
|
32
|
-
this.adapter = new import_adapter.DataVariantAdapter();
|
|
19
|
+
this.adapter = new _adapter.DataVariantAdapter();
|
|
33
20
|
}
|
|
21
|
+
|
|
34
22
|
/**
|
|
35
23
|
* 设置策略配置列表,仅保留 metadata.type === 'data_variant' 的策略。
|
|
36
24
|
*/
|
|
@@ -40,6 +28,7 @@ var DataVariantEvaluator = class {
|
|
|
40
28
|
getStrategyConfigs() {
|
|
41
29
|
return this.strategyConfigs;
|
|
42
30
|
}
|
|
31
|
+
|
|
43
32
|
/**
|
|
44
33
|
* 批量解析商品 Data Variant。
|
|
45
34
|
*
|
|
@@ -48,34 +37,21 @@ var DataVariantEvaluator = class {
|
|
|
48
37
|
resolveProducts(businessData) {
|
|
49
38
|
const strategyConfigs = businessData.strategyConfigs ? this.normalizeStrategyConfigs(businessData.strategyConfigs) : this.strategyConfigs;
|
|
50
39
|
const menuScopeMap = this.buildMenuScopeMap(businessData.menuList || []);
|
|
51
|
-
const scheduleTimePoints = this.buildScheduleTimePoints(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
);
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
businessData,
|
|
61
|
-
menuScopeMap
|
|
62
|
-
) : {
|
|
63
|
-
globalEffectiveRuleMap: /* @__PURE__ */ new Map(),
|
|
40
|
+
const scheduleTimePoints = this.buildScheduleTimePoints(strategyConfigs, businessData.scheduleList || []);
|
|
41
|
+
// metadata.data_variant_ids 存在时,接口已经完成规则计算;只有仍有商品缺少
|
|
42
|
+
// 该权威结果时才初始化本地策略引擎,避免 OS/接口与客户端重复评估。
|
|
43
|
+
const shouldEvaluateStrategies = businessData.products.some(product => this.requiresLocalStrategyEvaluation(product));
|
|
44
|
+
const {
|
|
45
|
+
globalEffectiveRuleMap,
|
|
46
|
+
rawResults
|
|
47
|
+
} = shouldEvaluateStrategies ? this.buildGlobalEffectiveRuleMap(strategyConfigs, businessData, menuScopeMap) : {
|
|
48
|
+
globalEffectiveRuleMap: new Map(),
|
|
64
49
|
rawResults: []
|
|
65
50
|
};
|
|
66
|
-
const products = businessData.products.map(
|
|
67
|
-
const resolvedProduct = this.resolveProduct(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
globalEffectiveRuleMap,
|
|
71
|
-
menuScopeMap
|
|
72
|
-
);
|
|
73
|
-
return this.resolveProductBundleItems(
|
|
74
|
-
resolvedProduct,
|
|
75
|
-
businessData,
|
|
76
|
-
globalEffectiveRuleMap,
|
|
77
|
-
menuScopeMap
|
|
78
|
-
);
|
|
51
|
+
const products = businessData.products.map(product => {
|
|
52
|
+
const resolvedProduct = this.resolveProduct(product, businessData, globalEffectiveRuleMap, menuScopeMap);
|
|
53
|
+
// 套餐子商品也可能携带 data_variants,需在同一策略上下文内继续评估并写回 bundle_item。
|
|
54
|
+
return this.resolveProductBundleItems(resolvedProduct, businessData, globalEffectiveRuleMap, menuScopeMap);
|
|
79
55
|
});
|
|
80
56
|
return {
|
|
81
57
|
products,
|
|
@@ -85,55 +61,51 @@ var DataVariantEvaluator = class {
|
|
|
85
61
|
rawResults
|
|
86
62
|
};
|
|
87
63
|
}
|
|
64
|
+
|
|
88
65
|
/**
|
|
89
66
|
* 根据 operator/field 判断条件是否依赖当前商品。
|
|
90
67
|
*/
|
|
91
68
|
getConditionScope(rule) {
|
|
92
|
-
if (rule.operator ===
|
|
93
|
-
|
|
94
|
-
if (rule.operator ===
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return "product";
|
|
98
|
-
if (rule.field === "product" || rule.field === "productIdAndVariantId") {
|
|
99
|
-
return "product";
|
|
69
|
+
if (rule.operator === 'schedule_match') return 'global';
|
|
70
|
+
if (rule.operator === 'menu_match') return 'product';
|
|
71
|
+
if (rule.operator === 'product_match') return 'product';
|
|
72
|
+
if (rule.field === 'product' || rule.field === 'productIdAndVariantId') {
|
|
73
|
+
return 'product';
|
|
100
74
|
}
|
|
101
|
-
return
|
|
75
|
+
return 'global';
|
|
102
76
|
}
|
|
77
|
+
|
|
103
78
|
/**
|
|
104
79
|
* 将餐牌 partyroom_package 预构建为 Map/Set 索引。
|
|
105
80
|
*/
|
|
106
81
|
buildMenuScopeMap(menuList) {
|
|
107
|
-
const map =
|
|
82
|
+
const map = new Map();
|
|
108
83
|
for (const menu of menuList) {
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (!menuId)
|
|
113
|
-
continue;
|
|
84
|
+
if (menu?.status && menu.status !== 'valid') continue;
|
|
85
|
+
const menuId = this.toNumber(menu?.form_record_id);
|
|
86
|
+
if (!menuId) continue;
|
|
114
87
|
const scope = {
|
|
115
88
|
isAllProducts: false,
|
|
116
|
-
collectionIds:
|
|
117
|
-
productKeys:
|
|
118
|
-
productAllVariantIds:
|
|
89
|
+
collectionIds: new Set(),
|
|
90
|
+
productKeys: new Set(),
|
|
91
|
+
productAllVariantIds: new Set()
|
|
119
92
|
};
|
|
120
93
|
const packageConfig = menu.partyroom_package;
|
|
121
|
-
const products = Array.isArray(packageConfig
|
|
122
|
-
if (
|
|
94
|
+
const products = Array.isArray(packageConfig?.products) ? packageConfig.products : [];
|
|
95
|
+
if (packageConfig?.type === 'product_all') {
|
|
123
96
|
scope.isAllProducts = true;
|
|
124
|
-
} else if (
|
|
97
|
+
} else if (packageConfig?.type === 'product_collection') {
|
|
125
98
|
for (const item of products) {
|
|
126
99
|
const collectionId = this.toNumber(item.product_collection_id);
|
|
127
100
|
if (collectionId) {
|
|
128
101
|
scope.collectionIds.add(collectionId);
|
|
129
102
|
}
|
|
130
103
|
}
|
|
131
|
-
} else if (
|
|
104
|
+
} else if (packageConfig?.type === 'products') {
|
|
132
105
|
for (const item of products) {
|
|
133
106
|
const productId = this.toNumber(item.product_id);
|
|
134
107
|
const variantId = this.toNumber(item.product_variant_id);
|
|
135
|
-
if (!productId)
|
|
136
|
-
continue;
|
|
108
|
+
if (!productId) continue;
|
|
137
109
|
if (variantId === 0) {
|
|
138
110
|
scope.productAllVariantIds.add(productId);
|
|
139
111
|
} else {
|
|
@@ -145,6 +117,7 @@ var DataVariantEvaluator = class {
|
|
|
145
117
|
}
|
|
146
118
|
return map;
|
|
147
119
|
}
|
|
120
|
+
|
|
148
121
|
/**
|
|
149
122
|
* 从当前策略中所有 schedule_match.value 绑定的 schedule_id 提取时间点。
|
|
150
123
|
*
|
|
@@ -152,77 +125,65 @@ var DataVariantEvaluator = class {
|
|
|
152
125
|
*/
|
|
153
126
|
buildScheduleTimePoints(strategyConfigs, scheduleList) {
|
|
154
127
|
const scheduleIds = this.collectScheduleIdsFromStrategies(strategyConfigs);
|
|
155
|
-
if (!scheduleIds.length || !scheduleList.length)
|
|
156
|
-
return [];
|
|
128
|
+
if (!scheduleIds.length || !scheduleList.length) return [];
|
|
157
129
|
const scheduleIdSet = new Set(scheduleIds);
|
|
158
|
-
const matchedSchedules = scheduleList.filter(
|
|
159
|
-
(schedule) => scheduleIdSet.has(Number(schedule.id))
|
|
160
|
-
);
|
|
130
|
+
const matchedSchedules = scheduleList.filter(schedule => scheduleIdSet.has(Number(schedule.id)));
|
|
161
131
|
return this.extractTimePointsFromSchedules(matchedSchedules);
|
|
162
132
|
}
|
|
133
|
+
|
|
163
134
|
/**
|
|
164
135
|
* 判断商品(含套餐子商品)是否仍需要本地执行策略条件。
|
|
165
136
|
* metadata.data_variant_ids 只要是数组,即使为空,也表示接口已经给出权威命中结果。
|
|
166
137
|
*/
|
|
167
138
|
requiresLocalStrategyEvaluation(product) {
|
|
168
139
|
const dataVariants = this.getProductDataVariants(product);
|
|
169
|
-
const hasConditionalVariant = dataVariants.some(
|
|
170
|
-
(variant) => Number(variant.data_variant_rule_id) !== 0
|
|
171
|
-
);
|
|
140
|
+
const hasConditionalVariant = dataVariants.some(variant => Number(variant.data_variant_rule_id) !== 0);
|
|
172
141
|
if (hasConditionalVariant && this.getAuthoritativeVariantPriorities(product) === null) {
|
|
173
142
|
return true;
|
|
174
143
|
}
|
|
175
144
|
const bundleGroups = Array.isArray(product.bundle_group) ? product.bundle_group : [];
|
|
176
|
-
return bundleGroups.some(
|
|
177
|
-
const bundleItems = Array.isArray(group
|
|
178
|
-
return bundleItems.some(
|
|
179
|
-
(item) => this.requiresLocalStrategyEvaluation(
|
|
180
|
-
this.toBundleItemDataVariantProduct(item)
|
|
181
|
-
)
|
|
182
|
-
);
|
|
145
|
+
return bundleGroups.some(group => {
|
|
146
|
+
const bundleItems = Array.isArray(group?.bundle_item) ? group.bundle_item : [];
|
|
147
|
+
return bundleItems.some(item => this.requiresLocalStrategyEvaluation(this.toBundleItemDataVariantProduct(item)));
|
|
183
148
|
});
|
|
184
149
|
}
|
|
150
|
+
|
|
185
151
|
/**
|
|
186
152
|
* 将接口返回的高 -> 低优先级 Variant ID 转成数值优先级。
|
|
187
153
|
* 返回 null 表示接口没有提供该字段;空 Map 表示已计算但没有任何命中。
|
|
188
154
|
*/
|
|
189
155
|
getAuthoritativeVariantPriorities(product) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if (!Array.isArray(rawIds))
|
|
193
|
-
return null;
|
|
156
|
+
const rawIds = product?.metadata?.data_variant_ids;
|
|
157
|
+
if (!Array.isArray(rawIds)) return null;
|
|
194
158
|
const orderedIds = [];
|
|
195
|
-
const seen =
|
|
159
|
+
const seen = new Set();
|
|
196
160
|
for (const rawId of rawIds) {
|
|
197
161
|
const id = this.normalizeDataVariantId(rawId);
|
|
198
|
-
if (id === null || seen.has(id))
|
|
199
|
-
continue;
|
|
162
|
+
if (id === null || seen.has(id)) continue;
|
|
200
163
|
seen.add(id);
|
|
201
164
|
orderedIds.push(id);
|
|
202
165
|
}
|
|
203
|
-
return new Map(
|
|
204
|
-
orderedIds.map((id, index) => [id, orderedIds.length - index])
|
|
205
|
-
);
|
|
166
|
+
return new Map(orderedIds.map((id, index) => [id, orderedIds.length - index]));
|
|
206
167
|
}
|
|
207
168
|
normalizeDataVariantId(value) {
|
|
208
|
-
if (value ===
|
|
209
|
-
return null;
|
|
169
|
+
if (value === undefined || value === null) return null;
|
|
210
170
|
const normalized = String(value).trim();
|
|
211
171
|
return normalized || null;
|
|
212
172
|
}
|
|
213
173
|
buildGlobalEffectiveRuleMap(strategyConfigs, businessData, menuScopeMap) {
|
|
214
|
-
const globalEffectiveRuleMap =
|
|
174
|
+
const globalEffectiveRuleMap = new Map();
|
|
215
175
|
const rawResults = [];
|
|
216
176
|
const engine = this.createEngine(businessData, menuScopeMap);
|
|
217
177
|
const context = this.adapter.prepareGlobalContext(businessData);
|
|
218
178
|
for (const config of strategyConfigs) {
|
|
219
|
-
if (!this.isStrategyActive(config))
|
|
220
|
-
|
|
221
|
-
|
|
179
|
+
if (!this.isStrategyActive(config)) continue;
|
|
180
|
+
const {
|
|
181
|
+
globalConfig,
|
|
182
|
+
productRules
|
|
183
|
+
} = this.splitStrategyConfig(config);
|
|
222
184
|
const result = engine.evaluate(globalConfig, context);
|
|
223
185
|
rawResults.push(result);
|
|
224
|
-
if (!result.applicable)
|
|
225
|
-
continue;
|
|
186
|
+
if (!result.applicable) continue;
|
|
226
187
|
globalEffectiveRuleMap.set(String(config.metadata.id), {
|
|
227
188
|
ruleId: String(config.metadata.id),
|
|
228
189
|
priority: this.getStrategyPriority(config),
|
|
@@ -231,25 +192,23 @@ var DataVariantEvaluator = class {
|
|
|
231
192
|
globalResult: result
|
|
232
193
|
});
|
|
233
194
|
}
|
|
234
|
-
return {
|
|
195
|
+
return {
|
|
196
|
+
globalEffectiveRuleMap,
|
|
197
|
+
rawResults
|
|
198
|
+
};
|
|
235
199
|
}
|
|
236
200
|
resolveProduct(product, businessData, globalEffectiveRuleMap, menuScopeMap) {
|
|
237
201
|
const dataVariants = this.getProductDataVariants(product);
|
|
238
|
-
if (!dataVariants.length)
|
|
239
|
-
return product;
|
|
202
|
+
if (!dataVariants.length) return product;
|
|
240
203
|
const matchedVariants = [];
|
|
241
204
|
const authoritativeVariantPriorities = this.getAuthoritativeVariantPriorities(product);
|
|
242
|
-
const settlementVariants = dataVariants.filter(
|
|
243
|
-
(variant) => variant.business_type === "multi_currency_settlement" && variant.status === "enable"
|
|
244
|
-
);
|
|
205
|
+
const settlementVariants = dataVariants.filter(variant => variant.business_type === 'multi_currency_settlement' && variant.status === 'enable');
|
|
245
206
|
for (const variant of dataVariants) {
|
|
246
|
-
if (variant.business_type ===
|
|
247
|
-
continue;
|
|
207
|
+
if (variant.business_type === 'multi_currency_settlement') continue;
|
|
248
208
|
if (authoritativeVariantPriorities !== null) {
|
|
249
209
|
const variantId = this.normalizeDataVariantId(variant.id);
|
|
250
|
-
const priority = variantId === null ?
|
|
251
|
-
if (priority ===
|
|
252
|
-
continue;
|
|
210
|
+
const priority = variantId === null ? undefined : authoritativeVariantPriorities.get(variantId);
|
|
211
|
+
if (priority === undefined) continue;
|
|
253
212
|
matchedVariants.push({
|
|
254
213
|
ruleId: String(variant.data_variant_rule_id),
|
|
255
214
|
priority,
|
|
@@ -258,11 +217,8 @@ var DataVariantEvaluator = class {
|
|
|
258
217
|
});
|
|
259
218
|
continue;
|
|
260
219
|
}
|
|
261
|
-
const rule = globalEffectiveRuleMap.get(
|
|
262
|
-
|
|
263
|
-
);
|
|
264
|
-
if (!rule)
|
|
265
|
-
continue;
|
|
220
|
+
const rule = globalEffectiveRuleMap.get(String(variant.data_variant_rule_id));
|
|
221
|
+
if (!rule) continue;
|
|
266
222
|
if (!this.evaluateProductRules(rule, product, businessData, menuScopeMap)) {
|
|
267
223
|
continue;
|
|
268
224
|
}
|
|
@@ -274,60 +230,45 @@ var DataVariantEvaluator = class {
|
|
|
274
230
|
});
|
|
275
231
|
}
|
|
276
232
|
const resolvedProduct = matchedVariants.length ? this.mergeMatchedVariants(product, matchedVariants) : product;
|
|
277
|
-
const availableSettlementOptions = this.resolveSettlementOptions(
|
|
278
|
-
|
|
279
|
-
product,
|
|
280
|
-
businessData,
|
|
281
|
-
globalEffectiveRuleMap,
|
|
282
|
-
menuScopeMap,
|
|
283
|
-
authoritativeVariantPriorities
|
|
284
|
-
);
|
|
285
|
-
if (!settlementVariants.length)
|
|
286
|
-
return resolvedProduct;
|
|
233
|
+
const availableSettlementOptions = this.resolveSettlementOptions(settlementVariants, product, businessData, globalEffectiveRuleMap, menuScopeMap, authoritativeVariantPriorities);
|
|
234
|
+
if (!settlementVariants.length) return resolvedProduct;
|
|
287
235
|
return {
|
|
288
236
|
...resolvedProduct,
|
|
289
237
|
available_settlement_options: availableSettlementOptions
|
|
290
238
|
};
|
|
291
239
|
}
|
|
240
|
+
|
|
292
241
|
/**
|
|
293
242
|
* 多货币 Data Variant 只生成候选列表,不参与商品字段覆盖。
|
|
294
243
|
* rule_id=0 是无条件默认价;同币种命中的条件价优先于默认价。
|
|
295
244
|
*/
|
|
296
245
|
resolveSettlementOptions(variants, product, businessData, globalEffectiveRuleMap, menuScopeMap, authoritativeVariantPriorities) {
|
|
297
|
-
if (!variants.length)
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
const settlement = (_a = variant.data) == null ? void 0 : _a.multi_currency_settlement;
|
|
302
|
-
if (!settlement || typeof settlement !== "object")
|
|
303
|
-
return [];
|
|
246
|
+
if (!variants.length) return [];
|
|
247
|
+
const candidates = variants.flatMap(variant => {
|
|
248
|
+
const settlement = variant.data?.multi_currency_settlement;
|
|
249
|
+
if (!settlement || typeof settlement !== 'object') return [];
|
|
304
250
|
const ruleId = String(variant.data_variant_rule_id);
|
|
305
251
|
const isDefault = Number(variant.data_variant_rule_id) === 0;
|
|
306
|
-
const rule = isDefault ?
|
|
252
|
+
const rule = isDefault ? undefined : globalEffectiveRuleMap.get(ruleId);
|
|
307
253
|
const variantId = this.normalizeDataVariantId(variant.id);
|
|
308
|
-
const authoritativePriority = variantId === null ?
|
|
254
|
+
const authoritativePriority = variantId === null ? undefined : authoritativeVariantPriorities?.get(variantId);
|
|
309
255
|
let available;
|
|
310
256
|
let priority;
|
|
311
257
|
if (isDefault) {
|
|
258
|
+
// rule 0 是无条件默认候选,不依赖接口命中 ID 或本地策略引擎。
|
|
312
259
|
available = true;
|
|
313
260
|
priority = Number.NEGATIVE_INFINITY;
|
|
314
261
|
} else if (authoritativeVariantPriorities !== null) {
|
|
315
|
-
|
|
316
|
-
|
|
262
|
+
// 数组存在(包括 [])即表示接口已经算过规则,不再在客户端二次判断。
|
|
263
|
+
available = authoritativePriority !== undefined;
|
|
264
|
+
priority = authoritativePriority ?? rule?.priority ?? Number.NEGATIVE_INFINITY;
|
|
317
265
|
} else {
|
|
318
|
-
available = Boolean(
|
|
319
|
-
|
|
320
|
-
rule,
|
|
321
|
-
product,
|
|
322
|
-
businessData,
|
|
323
|
-
menuScopeMap
|
|
324
|
-
)
|
|
325
|
-
);
|
|
326
|
-
priority = (rule == null ? void 0 : rule.priority) ?? Number.NEGATIVE_INFINITY;
|
|
266
|
+
available = Boolean(rule && this.evaluateProductRules(rule, product, businessData, menuScopeMap));
|
|
267
|
+
priority = rule?.priority ?? Number.NEGATIVE_INFINITY;
|
|
327
268
|
}
|
|
328
|
-
const settlementType = String(settlement.settlement_type ||
|
|
269
|
+
const settlementType = String(settlement.settlement_type || '');
|
|
329
270
|
const currencyProductId = this.toNumber(settlement.currency_product_id);
|
|
330
|
-
const settlementKey = settlementType ===
|
|
271
|
+
const settlementKey = settlementType === 'virtual_currency' ? `virtual_currency:${currencyProductId || ''}` : settlementType || `variant:${variant.id ?? ruleId}`;
|
|
331
272
|
return [{
|
|
332
273
|
key: settlementKey,
|
|
333
274
|
priority,
|
|
@@ -335,30 +276,31 @@ var DataVariantEvaluator = class {
|
|
|
335
276
|
option: {
|
|
336
277
|
...settlement,
|
|
337
278
|
settlement_type: settlementType,
|
|
338
|
-
...currencyProductId ? {
|
|
339
|
-
|
|
279
|
+
...(currencyProductId ? {
|
|
280
|
+
currency_product_id: currencyProductId
|
|
281
|
+
} : {}),
|
|
282
|
+
price: String(variant.data?.price ?? '0'),
|
|
340
283
|
data_variant_id: variant.id,
|
|
341
284
|
data_variant_rule_id: variant.data_variant_rule_id,
|
|
342
285
|
available,
|
|
343
|
-
disabled_reason: available ?
|
|
344
|
-
settlement.disabled_reason || "Not available for this purchase."
|
|
345
|
-
)
|
|
286
|
+
disabled_reason: available ? '' : String(settlement.disabled_reason || 'Not available for this purchase.')
|
|
346
287
|
}
|
|
347
288
|
}];
|
|
348
289
|
});
|
|
349
|
-
const grouped =
|
|
290
|
+
const grouped = new Map();
|
|
350
291
|
for (const candidate of candidates) {
|
|
351
292
|
const group = grouped.get(candidate.key) || [];
|
|
352
293
|
group.push(candidate);
|
|
353
294
|
grouped.set(candidate.key, group);
|
|
354
295
|
}
|
|
355
|
-
return Array.from(grouped.values()).map(
|
|
356
|
-
const matchedConditional = group.filter(
|
|
357
|
-
const defaultCandidate = group.find(
|
|
358
|
-
const unavailableCandidate = [...group].filter(
|
|
296
|
+
return Array.from(grouped.values()).map(group => {
|
|
297
|
+
const matchedConditional = group.filter(candidate => !candidate.isDefault && candidate.option.available).sort((a, b) => b.priority - a.priority)[0];
|
|
298
|
+
const defaultCandidate = group.find(candidate => candidate.isDefault);
|
|
299
|
+
const unavailableCandidate = [...group].filter(candidate => !candidate.option.available).sort((a, b) => b.priority - a.priority)[0];
|
|
359
300
|
return (matchedConditional || defaultCandidate || unavailableCandidate).option;
|
|
360
301
|
});
|
|
361
302
|
}
|
|
303
|
+
|
|
362
304
|
/**
|
|
363
305
|
* 解析套餐子商品上的 Data Variant 覆盖。
|
|
364
306
|
*
|
|
@@ -369,21 +311,14 @@ var DataVariantEvaluator = class {
|
|
|
369
311
|
if (!Array.isArray(bundleGroups) || bundleGroups.length === 0) {
|
|
370
312
|
return product;
|
|
371
313
|
}
|
|
372
|
-
const resolvedGroups = bundleGroups.map(
|
|
373
|
-
const bundleItems = group
|
|
314
|
+
const resolvedGroups = bundleGroups.map(group => {
|
|
315
|
+
const bundleItems = group?.bundle_item;
|
|
374
316
|
if (!Array.isArray(bundleItems) || bundleItems.length === 0) {
|
|
375
317
|
return group;
|
|
376
318
|
}
|
|
377
319
|
return {
|
|
378
320
|
...group,
|
|
379
|
-
bundle_item: bundleItems.map(
|
|
380
|
-
(item) => this.resolveBundleItem(
|
|
381
|
-
item,
|
|
382
|
-
businessData,
|
|
383
|
-
globalEffectiveRuleMap,
|
|
384
|
-
menuScopeMap
|
|
385
|
-
)
|
|
386
|
-
)
|
|
321
|
+
bundle_item: bundleItems.map(item => this.resolveBundleItem(item, businessData, globalEffectiveRuleMap, menuScopeMap))
|
|
387
322
|
};
|
|
388
323
|
});
|
|
389
324
|
return {
|
|
@@ -391,6 +326,7 @@ var DataVariantEvaluator = class {
|
|
|
391
326
|
bundle_group: resolvedGroups
|
|
392
327
|
};
|
|
393
328
|
}
|
|
329
|
+
|
|
394
330
|
/**
|
|
395
331
|
* 将 bundle_item 转为 DataVariantProduct 并评估 data_variants。
|
|
396
332
|
*/
|
|
@@ -399,14 +335,10 @@ var DataVariantEvaluator = class {
|
|
|
399
335
|
if (!this.getProductDataVariants(bundleProduct).length) {
|
|
400
336
|
return item;
|
|
401
337
|
}
|
|
402
|
-
const resolvedItem = this.resolveProduct(
|
|
403
|
-
bundleProduct,
|
|
404
|
-
businessData,
|
|
405
|
-
globalEffectiveRuleMap,
|
|
406
|
-
menuScopeMap
|
|
407
|
-
);
|
|
338
|
+
const resolvedItem = this.resolveProduct(bundleProduct, businessData, globalEffectiveRuleMap, menuScopeMap);
|
|
408
339
|
return this.mergeBundleItemResolvedData(item, resolvedItem);
|
|
409
340
|
}
|
|
341
|
+
|
|
410
342
|
/**
|
|
411
343
|
* bundle_item 的商品身份映射:bundle_product_id + bundle_variant_id。
|
|
412
344
|
*/
|
|
@@ -423,18 +355,20 @@ var DataVariantEvaluator = class {
|
|
|
423
355
|
metadata: item.metadata
|
|
424
356
|
};
|
|
425
357
|
}
|
|
358
|
+
|
|
426
359
|
/**
|
|
427
360
|
* 仅回写命中的字段,避免污染 bundle_item 的结构字段。
|
|
428
361
|
*/
|
|
429
362
|
mergeBundleItemResolvedData(originalItem, resolvedItem) {
|
|
430
|
-
var _a;
|
|
431
363
|
const appliedInfo = resolvedItem._dataVariant;
|
|
432
|
-
if (!
|
|
364
|
+
if (!appliedInfo?.appliedFields?.length) {
|
|
433
365
|
return originalItem;
|
|
434
366
|
}
|
|
435
|
-
const result = {
|
|
367
|
+
const result = {
|
|
368
|
+
...originalItem
|
|
369
|
+
};
|
|
436
370
|
for (const field of appliedInfo.appliedFields) {
|
|
437
|
-
if (resolvedItem[field] !==
|
|
371
|
+
if (resolvedItem[field] !== undefined) {
|
|
438
372
|
result[field] = resolvedItem[field];
|
|
439
373
|
}
|
|
440
374
|
}
|
|
@@ -442,20 +376,20 @@ var DataVariantEvaluator = class {
|
|
|
442
376
|
return result;
|
|
443
377
|
}
|
|
444
378
|
evaluateProductRules(rule, product, businessData, menuScopeMap) {
|
|
445
|
-
if (!rule.productRules.length)
|
|
446
|
-
return true;
|
|
379
|
+
if (!rule.productRules.length) return true;
|
|
447
380
|
const engine = this.createEngine(businessData, menuScopeMap);
|
|
448
381
|
const context = this.adapter.prepareProductContext(businessData, product);
|
|
449
382
|
const productOnlyConfig = {
|
|
450
383
|
...rule.strategyConfig,
|
|
451
384
|
conditions: {
|
|
452
|
-
operator:
|
|
385
|
+
operator: 'and',
|
|
453
386
|
rules: rule.productRules,
|
|
454
387
|
actionIds: rule.strategyConfig.conditions.actionIds || []
|
|
455
388
|
}
|
|
456
389
|
};
|
|
457
390
|
return engine.evaluate(productOnlyConfig, context).applicable;
|
|
458
391
|
}
|
|
392
|
+
|
|
459
393
|
/**
|
|
460
394
|
* 拆分策略条件。
|
|
461
395
|
*
|
|
@@ -465,7 +399,7 @@ var DataVariantEvaluator = class {
|
|
|
465
399
|
const conditions = config.conditions;
|
|
466
400
|
const globalRules = [];
|
|
467
401
|
const productRules = [];
|
|
468
|
-
if (conditions.operator !==
|
|
402
|
+
if (conditions.operator !== 'and') {
|
|
469
403
|
return {
|
|
470
404
|
globalConfig: {
|
|
471
405
|
...config,
|
|
@@ -479,7 +413,7 @@ var DataVariantEvaluator = class {
|
|
|
479
413
|
productRules.push(...this.flattenConditionRules(rule));
|
|
480
414
|
continue;
|
|
481
415
|
}
|
|
482
|
-
if (this.getConditionScope(rule) ===
|
|
416
|
+
if (this.getConditionScope(rule) === 'product') {
|
|
483
417
|
productRules.push(rule);
|
|
484
418
|
} else {
|
|
485
419
|
globalRules.push(rule);
|
|
@@ -489,7 +423,7 @@ var DataVariantEvaluator = class {
|
|
|
489
423
|
globalConfig: {
|
|
490
424
|
...config,
|
|
491
425
|
conditions: {
|
|
492
|
-
operator:
|
|
426
|
+
operator: 'and',
|
|
493
427
|
rules: globalRules,
|
|
494
428
|
actionIds: conditions.actionIds || []
|
|
495
429
|
}
|
|
@@ -499,62 +433,48 @@ var DataVariantEvaluator = class {
|
|
|
499
433
|
}
|
|
500
434
|
createEngine(businessData, menuScopeMap) {
|
|
501
435
|
const operatorHandlers = {
|
|
502
|
-
schedule_match: (fieldValue, compareValue) => this.evaluateScheduleMatch(
|
|
503
|
-
fieldValue,
|
|
504
|
-
compareValue,
|
|
505
|
-
businessData.scheduleList || []
|
|
506
|
-
),
|
|
436
|
+
schedule_match: (fieldValue, compareValue) => this.evaluateScheduleMatch(fieldValue, compareValue, businessData.scheduleList || []),
|
|
507
437
|
menu_match: (fieldValue, compareValue) => this.evaluateMenuMatch(fieldValue, compareValue, menuScopeMap),
|
|
508
438
|
array_intersects: (fieldValue, compareValue) => this.evaluateArrayIntersects(fieldValue, compareValue)
|
|
509
439
|
};
|
|
510
|
-
return new
|
|
440
|
+
return new _engine.StrategyEngine({
|
|
511
441
|
debug: false,
|
|
512
442
|
enableTrace: false,
|
|
513
443
|
operatorHandlers
|
|
514
444
|
});
|
|
515
445
|
}
|
|
516
446
|
evaluateScheduleMatch(fieldValue, compareValue, scheduleList) {
|
|
517
|
-
const scheduleDateTime = String(fieldValue ||
|
|
447
|
+
const scheduleDateTime = String(fieldValue || '');
|
|
518
448
|
const scheduleIds = this.normalizeNumberArray(compareValue);
|
|
519
|
-
if (!scheduleIds.length)
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
const matchedSchedules = scheduleList.filter(
|
|
524
|
-
(schedule) => scheduleIds.includes(Number(schedule.id))
|
|
525
|
-
);
|
|
526
|
-
return (0, import_getDateIsInSchedule.getDateIsInSchedule)(scheduleDateTime, matchedSchedules);
|
|
449
|
+
if (!scheduleIds.length) return true;
|
|
450
|
+
if (!scheduleDateTime || !scheduleList?.length) return false;
|
|
451
|
+
const matchedSchedules = scheduleList.filter(schedule => scheduleIds.includes(Number(schedule.id)));
|
|
452
|
+
return (0, _getDateIsInSchedule.getDateIsInSchedule)(scheduleDateTime, matchedSchedules);
|
|
527
453
|
}
|
|
528
454
|
evaluateMenuMatch(fieldValue, compareValue, menuScopeMap) {
|
|
529
455
|
const menuIds = this.normalizeNumberArray(compareValue);
|
|
530
|
-
if (!menuIds.length)
|
|
531
|
-
return true;
|
|
456
|
+
if (!menuIds.length) return true;
|
|
532
457
|
for (const menuId of menuIds) {
|
|
533
458
|
const scope = menuScopeMap.get(menuId);
|
|
534
|
-
if (!scope)
|
|
535
|
-
|
|
536
|
-
if (this.isProductInMenuScope(fieldValue, scope))
|
|
537
|
-
return true;
|
|
459
|
+
if (!scope) continue;
|
|
460
|
+
if (this.isProductInMenuScope(fieldValue, scope)) return true;
|
|
538
461
|
}
|
|
539
462
|
return false;
|
|
540
463
|
}
|
|
541
464
|
evaluateArrayIntersects(fieldValue, compareValue) {
|
|
542
465
|
const fieldValues = this.normalizeComparableArray(fieldValue);
|
|
543
466
|
const compareValues = this.normalizeComparableArray(compareValue);
|
|
544
|
-
if (!fieldValues.length || !compareValues.length)
|
|
545
|
-
return false;
|
|
467
|
+
if (!fieldValues.length || !compareValues.length) return false;
|
|
546
468
|
const compareSet = new Set(compareValues);
|
|
547
|
-
return fieldValues.some(
|
|
469
|
+
return fieldValues.some(item => compareSet.has(item));
|
|
548
470
|
}
|
|
549
471
|
collectScheduleIdsFromStrategies(strategyConfigs) {
|
|
550
|
-
const scheduleIds =
|
|
472
|
+
const scheduleIds = new Set();
|
|
551
473
|
for (const config of strategyConfigs) {
|
|
552
|
-
if (!this.isStrategyActive(config))
|
|
553
|
-
continue;
|
|
474
|
+
if (!this.isStrategyActive(config)) continue;
|
|
554
475
|
const rules = this.flattenConditionRules(config.conditions);
|
|
555
476
|
for (const rule of rules) {
|
|
556
|
-
if (rule.operator !==
|
|
557
|
-
continue;
|
|
477
|
+
if (rule.operator !== 'schedule_match') continue;
|
|
558
478
|
for (const scheduleId of this.normalizeNumberArray(rule.value)) {
|
|
559
479
|
scheduleIds.add(scheduleId);
|
|
560
480
|
}
|
|
@@ -563,95 +483,89 @@ var DataVariantEvaluator = class {
|
|
|
563
483
|
return Array.from(scheduleIds);
|
|
564
484
|
}
|
|
565
485
|
extractTimePointsFromSchedules(schedules) {
|
|
566
|
-
const timePoints =
|
|
486
|
+
const timePoints = new Set();
|
|
567
487
|
for (const schedule of schedules) {
|
|
568
488
|
switch (schedule.type) {
|
|
569
|
-
case
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
case "time-slots": {
|
|
575
|
-
const slots = Array.isArray(schedule.time_slot) ? schedule.time_slot : [];
|
|
576
|
-
for (const slot of slots) {
|
|
577
|
-
this.addRawTimePoint(timePoints, slot.start_time);
|
|
578
|
-
this.addRawTimePoint(timePoints, slot.end_time);
|
|
489
|
+
case 'standard':
|
|
490
|
+
{
|
|
491
|
+
this.addDateTimePoint(timePoints, schedule.start_time);
|
|
492
|
+
this.addDateTimePoint(timePoints, schedule.end_time);
|
|
493
|
+
break;
|
|
579
494
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
495
|
+
case 'time-slots':
|
|
496
|
+
{
|
|
497
|
+
const slots = Array.isArray(schedule.time_slot) ? schedule.time_slot : [];
|
|
498
|
+
for (const slot of slots) {
|
|
499
|
+
this.addRawTimePoint(timePoints, slot.start_time);
|
|
500
|
+
this.addRawTimePoint(timePoints, slot.end_time);
|
|
501
|
+
}
|
|
502
|
+
break;
|
|
503
|
+
}
|
|
504
|
+
case 'designation':
|
|
505
|
+
{
|
|
506
|
+
const designations = Array.isArray(schedule.designation) ? schedule.designation : schedule.designation ? [schedule.designation] : [];
|
|
507
|
+
for (const designation of designations) {
|
|
508
|
+
this.addRawTimePoint(timePoints, designation.start_time);
|
|
509
|
+
this.addRawTimePoint(timePoints, designation.end_time);
|
|
510
|
+
}
|
|
511
|
+
break;
|
|
587
512
|
}
|
|
588
|
-
break;
|
|
589
|
-
}
|
|
590
513
|
default:
|
|
591
514
|
break;
|
|
592
515
|
}
|
|
593
516
|
}
|
|
594
|
-
return Array.from(timePoints).sort(
|
|
595
|
-
(a, b) => this.timeToMinutes(a) - this.timeToMinutes(b)
|
|
596
|
-
);
|
|
517
|
+
return Array.from(timePoints).sort((a, b) => this.timeToMinutes(a) - this.timeToMinutes(b));
|
|
597
518
|
}
|
|
598
519
|
addDateTimePoint(points, value) {
|
|
599
520
|
const time = this.extractTimeFromDateTime(value);
|
|
600
|
-
if (time)
|
|
601
|
-
points.add(time);
|
|
521
|
+
if (time) points.add(time);
|
|
602
522
|
}
|
|
603
523
|
addRawTimePoint(points, value) {
|
|
604
524
|
const time = this.normalizeTime(value);
|
|
605
|
-
if (time)
|
|
606
|
-
points.add(time);
|
|
525
|
+
if (time) points.add(time);
|
|
607
526
|
}
|
|
608
527
|
extractTimeFromDateTime(value) {
|
|
609
|
-
if (!value)
|
|
610
|
-
return null;
|
|
528
|
+
if (!value) return null;
|
|
611
529
|
const match = value.match(/(\d{1,2}):(\d{2})/);
|
|
612
|
-
if (!match)
|
|
613
|
-
|
|
614
|
-
return `${match[1].padStart(2, "0")}:${match[2]}`;
|
|
530
|
+
if (!match) return null;
|
|
531
|
+
return `${match[1].padStart(2, '0')}:${match[2]}`;
|
|
615
532
|
}
|
|
616
533
|
normalizeTime(value) {
|
|
617
|
-
if (!value)
|
|
618
|
-
return null;
|
|
534
|
+
if (!value) return null;
|
|
619
535
|
const match = value.match(/^(\d{1,2}):(\d{2})/);
|
|
620
|
-
if (!match)
|
|
621
|
-
|
|
622
|
-
return `${match[1].padStart(2, "0")}:${match[2]}`;
|
|
536
|
+
if (!match) return null;
|
|
537
|
+
return `${match[1].padStart(2, '0')}:${match[2]}`;
|
|
623
538
|
}
|
|
624
539
|
timeToMinutes(value) {
|
|
625
|
-
const [hour, minute] = value.split(
|
|
626
|
-
if (!Number.isFinite(hour) || !Number.isFinite(minute))
|
|
627
|
-
return 0;
|
|
540
|
+
const [hour, minute] = value.split(':').map(item => Number(item));
|
|
541
|
+
if (!Number.isFinite(hour) || !Number.isFinite(minute)) return 0;
|
|
628
542
|
return hour * 60 + minute;
|
|
629
543
|
}
|
|
630
544
|
isProductInMenuScope(product, scope) {
|
|
631
|
-
if (scope.isAllProducts)
|
|
632
|
-
|
|
633
|
-
if (!product || typeof product !== "object")
|
|
634
|
-
return false;
|
|
545
|
+
if (scope.isAllProducts) return true;
|
|
546
|
+
if (!product || typeof product !== 'object') return false;
|
|
635
547
|
const productId = this.toNumber(product.id ?? product.product_id);
|
|
636
548
|
const variantId = this.toNumber(product.product_variant_id);
|
|
637
549
|
const productKey = this.buildProductKey(productId, variantId);
|
|
638
|
-
const collectionIds = Array.isArray(product.collection_ids) ? product.collection_ids.map(
|
|
639
|
-
return collectionIds.some(
|
|
550
|
+
const collectionIds = Array.isArray(product.collection_ids) ? product.collection_ids.map(id => this.toNumber(id)) : [];
|
|
551
|
+
return collectionIds.some(id => scope.collectionIds.has(id)) || scope.productKeys.has(productKey) || scope.productAllVariantIds.has(productId);
|
|
640
552
|
}
|
|
641
553
|
mergeMatchedVariants(product, matchedVariants) {
|
|
642
|
-
const original = {
|
|
554
|
+
const original = {
|
|
555
|
+
...product
|
|
556
|
+
};
|
|
643
557
|
const sortedVariants = [...matchedVariants].sort((a, b) => {
|
|
644
|
-
if (a.priority !== b.priority)
|
|
645
|
-
return a.priority - b.priority;
|
|
558
|
+
if (a.priority !== b.priority) return a.priority - b.priority;
|
|
646
559
|
return Number(a.ruleId) - Number(b.ruleId);
|
|
647
560
|
});
|
|
648
|
-
const result = {
|
|
561
|
+
const result = {
|
|
562
|
+
...product
|
|
563
|
+
};
|
|
649
564
|
const appliedRuleIds = [];
|
|
650
|
-
const appliedFields =
|
|
565
|
+
const appliedFields = new Set();
|
|
651
566
|
for (const matched of sortedVariants) {
|
|
652
567
|
for (const [key, value] of Object.entries(matched.data)) {
|
|
653
|
-
if (value ===
|
|
654
|
-
continue;
|
|
568
|
+
if (value === undefined) continue;
|
|
655
569
|
result[key] = value;
|
|
656
570
|
appliedFields.add(key);
|
|
657
571
|
}
|
|
@@ -659,11 +573,7 @@ var DataVariantEvaluator = class {
|
|
|
659
573
|
}
|
|
660
574
|
result._dataVariant = {
|
|
661
575
|
appliedRuleIds,
|
|
662
|
-
appliedVariantIds: Array.from(
|
|
663
|
-
new Set(
|
|
664
|
-
[...sortedVariants].reverse().map((matched) => this.normalizeDataVariantId(matched.variant.id)).filter((id) => id !== null)
|
|
665
|
-
)
|
|
666
|
-
),
|
|
576
|
+
appliedVariantIds: Array.from(new Set([...sortedVariants].reverse().map(matched => this.normalizeDataVariantId(matched.variant.id)).filter(id => id !== null))),
|
|
667
577
|
appliedFields: Array.from(appliedFields),
|
|
668
578
|
original
|
|
669
579
|
};
|
|
@@ -673,31 +583,20 @@ var DataVariantEvaluator = class {
|
|
|
673
583
|
return Array.isArray(product.data_variants) ? product.data_variants : [];
|
|
674
584
|
}
|
|
675
585
|
normalizeStrategyConfigs(configs) {
|
|
676
|
-
return configs.filter(
|
|
677
|
-
(config) => {
|
|
678
|
-
var _a;
|
|
679
|
-
return ((_a = config == null ? void 0 : config.metadata) == null ? void 0 : _a.type) === "data_variant";
|
|
680
|
-
}
|
|
681
|
-
);
|
|
586
|
+
return configs.filter(config => config?.metadata?.type === 'data_variant');
|
|
682
587
|
}
|
|
683
588
|
isStrategyActive(config) {
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
return !status || status === "active";
|
|
589
|
+
const status = config.metadata.custom?.status;
|
|
590
|
+
return !status || status === 'active';
|
|
687
591
|
}
|
|
688
592
|
getStrategyPriority(config) {
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
return priority;
|
|
693
|
-
return Math.max(
|
|
694
|
-
0,
|
|
695
|
-
...config.actions.map((action) => Number(action.priority || 0))
|
|
696
|
-
);
|
|
593
|
+
const priority = Number(config.metadata.custom?.priority);
|
|
594
|
+
if (Number.isFinite(priority)) return priority;
|
|
595
|
+
return Math.max(0, ...config.actions.map(action => Number(action.priority || 0)));
|
|
697
596
|
}
|
|
698
597
|
createAlwaysTrueConditions(actionIds) {
|
|
699
598
|
return {
|
|
700
|
-
operator:
|
|
599
|
+
operator: 'and',
|
|
701
600
|
rules: [],
|
|
702
601
|
actionIds
|
|
703
602
|
};
|
|
@@ -714,18 +613,16 @@ var DataVariantEvaluator = class {
|
|
|
714
613
|
return rules;
|
|
715
614
|
}
|
|
716
615
|
isConditionGroup(rule) {
|
|
717
|
-
return
|
|
616
|
+
return 'rules' in rule && Array.isArray(rule.rules);
|
|
718
617
|
}
|
|
719
618
|
normalizeNumberArray(value) {
|
|
720
|
-
if (!Array.isArray(value))
|
|
721
|
-
|
|
722
|
-
return value.map((item) => this.toNumber(item)).filter((item) => item > 0);
|
|
619
|
+
if (!Array.isArray(value)) return [];
|
|
620
|
+
return value.map(item => this.toNumber(item)).filter(item => item > 0);
|
|
723
621
|
}
|
|
724
622
|
normalizeComparableArray(value) {
|
|
725
|
-
const list = Array.isArray(value) ? value : value == null || value ===
|
|
726
|
-
const normalized = list.map(
|
|
727
|
-
if (item == null || item ===
|
|
728
|
-
return "";
|
|
623
|
+
const list = Array.isArray(value) ? value : value == null || value === '' ? [] : [value];
|
|
624
|
+
const normalized = list.map(item => {
|
|
625
|
+
if (item == null || item === '') return '';
|
|
729
626
|
const parsed = Number(item);
|
|
730
627
|
return Number.isFinite(parsed) ? String(parsed) : String(item).trim();
|
|
731
628
|
}).filter(Boolean);
|
|
@@ -738,9 +635,6 @@ var DataVariantEvaluator = class {
|
|
|
738
635
|
const parsed = Number(value);
|
|
739
636
|
return Number.isFinite(parsed) ? parsed : 0;
|
|
740
637
|
}
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
0 && (module.exports = {
|
|
745
|
-
DataVariantEvaluator
|
|
746
|
-
});
|
|
638
|
+
}
|
|
639
|
+
exports.DataVariantEvaluator = DataVariantEvaluator;
|
|
640
|
+
var _default = exports.default = DataVariantEvaluator;
|