@pisell/pisellos 0.0.569 → 0.10.2
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 +10 -6
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -3
- package/dist/model/strategy/adapter/promotion/index.js +9 -0
- package/dist/model/strategy/adapter/walletPass/evaluator.js +7 -5
- package/dist/model/strategy/adapter/walletPass/example.js +26 -3
- package/dist/model/strategy/adapter/walletPass/index.js +5 -5
- package/dist/model/strategy/adapter/walletPass/type.d.ts +0 -3
- package/dist/model/strategy/adapter/walletPass/utils.d.ts +0 -26
- package/dist/model/strategy/adapter/walletPass/utils.js +17 -92
- package/dist/model/strategy/strategy-example.js +19 -5
- package/dist/modules/BaseModule.d.ts +1 -1
- package/dist/modules/BaseModule.js +8 -10
- package/dist/modules/Cart/index.js +3 -0
- package/dist/modules/Cart/utils/cartProduct.js +1 -0
- package/dist/modules/Cart/utils/cartResource.js +0 -2
- package/dist/modules/Cart/utils/changePrice.js +9 -16
- package/dist/modules/Date/index.js +5 -1
- package/dist/modules/Discount/index.d.ts +0 -1
- package/dist/modules/Discount/index.js +7 -22
- package/dist/modules/Discount/types.d.ts +0 -1
- package/dist/modules/OpenData/index.js +2 -0
- package/dist/modules/Order/index.js +70 -40
- package/dist/modules/Payment/index.js +162 -97
- package/dist/modules/Payment/types.d.ts +4 -8
- package/dist/modules/Payment/walletpass.d.ts +0 -2
- package/dist/modules/Payment/walletpass.js +5 -4
- package/dist/modules/ProductList/index.d.ts +1 -1
- package/dist/modules/ProductList/index.js +3 -12
- package/dist/modules/ProductList/types.d.ts +0 -1
- package/dist/modules/Rules/index.js +126 -427
- package/dist/modules/SalesSummary/utils.js +1 -2
- package/dist/modules/Schedule/getDateIsInSchedule.js +0 -5
- package/dist/modules/Schedule/index.js +1 -0
- package/dist/modules/Schedule/utils.js +1 -0
- package/dist/modules/Step/index.js +1 -0
- package/dist/modules/Summary/utils.js +22 -43
- package/dist/plugins/request.js +4 -1
- package/dist/plugins/window.js +6 -2
- package/dist/server/index.js +129 -97
- package/dist/server/modules/menu/index.js +41 -32
- package/dist/server/modules/order/index.js +4 -2
- package/dist/server/modules/products/index.js +42 -24
- package/dist/server/modules/quotation/index.js +38 -29
- package/dist/server/modules/resource/index.js +4 -3
- package/dist/server/modules/schedule/index.js +35 -27
- package/dist/server/utils/product.js +1 -0
- package/dist/solution/BaseSales/index.js +41 -38
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingByStep/index.js +60 -11
- package/dist/solution/BookingByStep/utils/capacity.js +11 -1
- package/dist/solution/BookingByStep/utils/resources.js +3 -1
- package/dist/solution/BookingByStep/utils/timeslots.js +43 -2
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.js +2 -0
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +7 -6
- package/dist/solution/BookingTicket/utils/scan/handleScan.js +31 -25
- package/dist/solution/BookingTicket/utils/scan/index.js +10 -6
- package/dist/solution/BuyTickets/index.js +12 -9
- package/dist/solution/Checkout/index.js +252 -177
- package/dist/solution/Checkout/utils/index.js +16 -4
- package/dist/solution/RegisterAndLogin/index.js +76 -30
- package/dist/solution/ScanOrder/index.js +60 -50
- package/dist/solution/ShopDiscount/index.js +14 -15
- package/dist/solution/ShopDiscount/types.d.ts +4 -5
- package/dist/solution/ShopDiscount/utils.d.ts +0 -9
- package/dist/solution/ShopDiscount/utils.js +0 -9
- package/dist/solution/VenueBooking/index.d.ts +3 -31
- package/dist/solution/VenueBooking/index.js +496 -651
- package/dist/solution/VenueBooking/types.d.ts +1 -3
- package/dist/solution/VenueBooking/types.js +0 -1
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
- package/dist/solution/VenueBooking/utils/dateSummary.js +25 -12
- package/dist/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
- package/dist/solution/VenueBooking/utils/timeSlot.js +4 -9
- package/dist/types/index.d.ts +1 -1
- package/dist/utils/task.js +18 -15
- package/dist/utils/watch.js +1 -0
- package/lib/apis/picoding.js +0 -2
- package/lib/core/index.js +132 -130
- package/lib/effects/index.js +57 -46
- package/lib/index.d.ts +0 -1
- package/lib/index.js +50 -92
- package/lib/model/index.js +21 -14
- package/lib/model/strategy/adapter/dataVariant/adapter.js +50 -38
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +236 -162
- package/lib/model/strategy/adapter/dataVariant/examples.js +237 -229
- package/lib/model/strategy/adapter/dataVariant/index.js +34 -39
- package/lib/model/strategy/adapter/dataVariant/type.js +28 -57
- package/lib/model/strategy/adapter/index.js +64 -100
- package/lib/model/strategy/adapter/itemRule/adapter.js +144 -156
- package/lib/model/strategy/adapter/itemRule/evaluator.js +48 -36
- package/lib/model/strategy/adapter/itemRule/examples.js +225 -295
- package/lib/model/strategy/adapter/itemRule/index.js +57 -83
- package/lib/model/strategy/adapter/itemRule/type.js +36 -97
- package/lib/model/strategy/adapter/promotion/adapter.js +63 -84
- package/lib/model/strategy/adapter/promotion/evaluator.js +231 -381
- package/lib/model/strategy/adapter/promotion/examples.js +159 -139
- package/lib/model/strategy/adapter/promotion/index.js +49 -1
- package/lib/model/strategy/adapter/promotion/type.js +35 -199
- package/lib/model/strategy/adapter/type.js +16 -4
- package/lib/model/strategy/adapter/walletPass/evaluator.js +152 -180
- package/lib/model/strategy/adapter/walletPass/example.js +190 -217
- package/lib/model/strategy/adapter/walletPass/index.js +51 -75
- package/lib/model/strategy/adapter/walletPass/locales.js +58 -36
- package/lib/model/strategy/adapter/walletPass/type.d.ts +0 -3
- package/lib/model/strategy/adapter/walletPass/type.js +16 -4
- package/lib/model/strategy/adapter/walletPass/utils.d.ts +0 -26
- package/lib/model/strategy/adapter/walletPass/utils.js +383 -678
- package/lib/model/strategy/engine.js +168 -270
- package/lib/model/strategy/index.js +34 -49
- package/lib/model/strategy/strategy-example.js +239 -243
- package/lib/model/strategy/type.js +40 -100
- package/lib/modules/Account/index.js +53 -39
- package/lib/modules/Account/types.js +33 -20
- package/lib/modules/AccountList/index.js +154 -116
- package/lib/modules/AccountList/types.js +31 -30
- package/lib/modules/AccountList/utils.js +30 -18
- package/lib/modules/BaseModule.d.ts +1 -1
- package/lib/modules/BaseModule.js +46 -25
- package/lib/modules/BookingContext/index.js +136 -158
- package/lib/modules/BookingContext/types.js +32 -46
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +143 -131
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +82 -75
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +150 -170
- package/lib/modules/BookingContext/utils/flexible.js +55 -38
- package/lib/modules/BookingContext/utils/formatResourceList.js +34 -19
- package/lib/modules/BookingContext/utils/index.js +41 -124
- package/lib/modules/BookingContext/utils/noResource.js +70 -58
- package/lib/modules/BookingContext/utils/orderLineDisplay.js +41 -14
- package/lib/modules/BookingContext/utils/productExtend.js +155 -202
- package/lib/modules/BookingContext/utils/resourceErrors.js +53 -53
- package/lib/modules/BookingContext/utils/resourceSelection.js +41 -19
- package/lib/modules/BookingContext/utils/resources.js +167 -209
- package/lib/modules/BookingContext/utils/serviceTimes.js +116 -115
- package/lib/modules/BookingContext/utils/timeSlices.js +80 -70
- package/lib/modules/Cart/index.js +124 -170
- package/lib/modules/Cart/types.js +51 -46
- package/lib/modules/Cart/utils/cartAccount.js +39 -40
- package/lib/modules/Cart/utils/cartDate.js +61 -56
- package/lib/modules/Cart/utils/cartDiscount.js +33 -28
- package/lib/modules/Cart/utils/cartNote.js +32 -27
- package/lib/modules/Cart/utils/cartProduct.js +251 -321
- package/lib/modules/Cart/utils/cartRelationForms.js +35 -29
- package/lib/modules/Cart/utils/cartResource.js +78 -72
- package/lib/modules/Cart/utils/changePrice.js +50 -28
- package/lib/modules/Cart/utils/index.js +48 -106
- package/lib/modules/Customer/constants.js +34 -13
- package/lib/modules/Customer/index.js +169 -232
- package/lib/modules/Customer/types.js +35 -38
- package/lib/modules/Date/index.js +115 -116
- package/lib/modules/Date/types.js +28 -16
- package/lib/modules/Date/utils.js +123 -174
- package/lib/modules/Discount/index.d.ts +0 -1
- package/lib/modules/Discount/index.js +128 -130
- package/lib/modules/Discount/types.d.ts +0 -1
- package/lib/modules/Discount/types.js +31 -9
- package/lib/modules/Guests/index.js +56 -30
- package/lib/modules/Guests/types.js +33 -23
- package/lib/modules/Holder/index.js +189 -209
- package/lib/modules/Holder/types.js +16 -4
- package/lib/modules/Holder/utils.js +49 -20
- package/lib/modules/OpenData/index.js +76 -69
- package/lib/modules/OpenData/types.js +16 -4
- package/lib/modules/OpenData/utils.js +78 -44
- package/lib/modules/Order/index.js +1909 -1572
- package/lib/modules/Order/types.js +35 -78
- package/lib/modules/Order/utils/bundleDiscountHydration.js +74 -41
- package/lib/modules/Order/utils/manualProductDiscount.js +123 -124
- package/lib/modules/Order/utils/orderCollectionIdentity.js +210 -148
- package/lib/modules/Order/utils.js +634 -799
- package/lib/modules/Payment/cash.js +33 -20
- package/lib/modules/Payment/cashRecommendationAlgorithm.js +76 -145
- package/lib/modules/Payment/eftpos.js +30 -16
- package/lib/modules/Payment/index.js +378 -518
- package/lib/modules/Payment/mx51.js +0 -1
- package/lib/modules/Payment/types.d.ts +4 -8
- package/lib/modules/Payment/types.js +107 -216
- package/lib/modules/Payment/utils.js +48 -51
- package/lib/modules/Payment/walletpass.d.ts +0 -2
- package/lib/modules/Payment/walletpass.js +211 -226
- package/lib/modules/Product/index.js +46 -51
- package/lib/modules/Product/types.js +16 -4
- package/lib/modules/Product/utils.js +33 -32
- package/lib/modules/ProductList/index.d.ts +1 -1
- package/lib/modules/ProductList/index.js +117 -117
- package/lib/modules/ProductList/types.d.ts +0 -1
- package/lib/modules/ProductList/types.js +31 -9
- package/lib/modules/Quotation/index.js +100 -66
- package/lib/modules/Quotation/types.js +16 -4
- package/lib/modules/Resource/index.js +59 -27
- package/lib/modules/Resource/types.js +32 -22
- package/lib/modules/Resource/utils.js +38 -30
- package/lib/modules/ResourcePlanner/index.js +61 -60
- package/lib/modules/ResourcePlanner/planner.js +384 -346
- package/lib/modules/ResourcePlanner/types.js +16 -4
- package/lib/modules/Rules/index.js +903 -1475
- package/lib/modules/Rules/types.js +40 -17
- package/lib/modules/SalesSummary/index.js +90 -85
- package/lib/modules/SalesSummary/types.js +16 -4
- package/lib/modules/SalesSummary/utils.js +427 -351
- package/lib/modules/ScanOrderLogger/index.js +79 -59
- package/lib/modules/ScanOrderLogger/providers/feishu.js +78 -54
- package/lib/modules/ScanOrderLogger/providers/grafana.js +36 -13
- package/lib/modules/ScanOrderLogger/types.js +16 -4
- package/lib/modules/Schedule/getDateIsInSchedule.js +163 -339
- package/lib/modules/Schedule/index.js +114 -100
- package/lib/modules/Schedule/type.js +16 -4
- package/lib/modules/Schedule/types.js +16 -4
- package/lib/modules/Schedule/utils.js +291 -433
- package/lib/modules/Step/index.js +52 -40
- package/lib/modules/Step/tyeps.js +16 -4
- package/lib/modules/Summary/index.js +71 -66
- package/lib/modules/Summary/types.js +16 -4
- package/lib/modules/Summary/utils.js +418 -791
- package/lib/modules/SurchargeList/index.js +60 -46
- package/lib/modules/SurchargeList/types.js +16 -4
- package/lib/modules/index.js +63 -245
- package/lib/plugins/app.js +16 -4
- package/lib/plugins/index.js +25 -36
- package/lib/plugins/request.js +126 -137
- package/lib/plugins/shopStore.js +16 -4
- package/lib/plugins/user.js +16 -4
- package/lib/plugins/window.js +179 -171
- package/lib/server/index.js +2337 -2675
- package/lib/server/modules/floor-plan/index.js +123 -102
- package/lib/server/modules/floor-plan/types.js +30 -15
- package/lib/server/modules/index.js +68 -106
- package/lib/server/modules/menu/index.js +122 -146
- package/lib/server/modules/menu/types.js +31 -18
- package/lib/server/modules/order/index.js +642 -567
- package/lib/server/modules/order/types.js +32 -117
- package/lib/server/modules/order/utils/filterBookings.js +194 -219
- package/lib/server/modules/order/utils/filterOrders.js +92 -118
- package/lib/server/modules/payment/index.js +83 -59
- package/lib/server/modules/payment/types.js +16 -4
- package/lib/server/modules/products/index.js +459 -575
- package/lib/server/modules/products/types.js +34 -44
- package/lib/server/modules/quotation/index.js +172 -137
- package/lib/server/modules/quotation/types.js +31 -21
- package/lib/server/modules/resource/index.js +184 -213
- package/lib/server/modules/resource/types.js +33 -42
- package/lib/server/modules/schedule/index.js +123 -135
- package/lib/server/modules/schedule/types.js +21 -14
- package/lib/server/modules/schedule/utils.js +163 -334
- package/lib/server/types.js +16 -4
- package/lib/server/utils/index.js +23 -25
- package/lib/server/utils/product.js +139 -196
- package/lib/server/utils/schedule.js +41 -34
- package/lib/server/utils/small-ticket.js +456 -478
- package/lib/server/utils/time.js +49 -40
- package/lib/solution/BaseSales/index.js +1016 -850
- package/lib/solution/BaseSales/types.js +37 -41
- package/lib/solution/BaseSales/utils/cartPromotion.js +460 -611
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +105 -85
- package/lib/solution/BaseSales/utils/quotationPrice.js +114 -56
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +143 -102
- package/lib/solution/BaseSales/utils.js +140 -155
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingByStep/index.js +1340 -1530
- package/lib/solution/BookingByStep/types.js +99 -40
- package/lib/solution/BookingByStep/utils/capacity.js +160 -192
- package/lib/solution/BookingByStep/utils/products.js +52 -42
- package/lib/solution/BookingByStep/utils/resources.js +330 -527
- package/lib/solution/BookingByStep/utils/stock.js +44 -65
- package/lib/solution/BookingByStep/utils/timeslots.js +131 -129
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.js +459 -543
- package/lib/solution/BookingTicket/types.js +77 -99
- package/lib/solution/BookingTicket/utils/addProductDecision.js +184 -219
- package/lib/solution/BookingTicket/utils/addTimeAvailability.js +89 -58
- package/lib/solution/BookingTicket/utils/bookingStatus.js +78 -107
- package/lib/solution/BookingTicket/utils/cartView.js +94 -110
- package/lib/solution/BookingTicket/utils/exampleData.js +0 -185
- package/lib/solution/BookingTicket/utils/orderCustomer.js +41 -18
- package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +86 -219
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +93 -144
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +91 -79
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +41 -54
- package/lib/solution/BookingTicket/utils/scan/handleScan.js +81 -84
- package/lib/solution/BookingTicket/utils/scan/index.js +104 -98
- package/lib/solution/BookingTicket/utils/scan/scanCache.js +43 -90
- package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +64 -52
- package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +58 -56
- package/lib/solution/BuyTickets/index.js +70 -67
- package/lib/solution/BuyTickets/types.js +38 -22
- package/lib/solution/Checkout/index.js +1158 -1451
- package/lib/solution/Checkout/types.js +61 -91
- package/lib/solution/Checkout/utils/index.js +156 -228
- package/lib/solution/PlaceOrder/index.js +0 -55
- package/lib/solution/RegisterAndLogin/config.js +460 -493
- package/lib/solution/RegisterAndLogin/index.js +630 -633
- package/lib/solution/RegisterAndLogin/types.js +76 -189
- package/lib/solution/RegisterAndLogin/utils.js +125 -183
- package/lib/solution/Sales/index.js +320 -317
- package/lib/solution/Sales/types.js +33 -27
- package/lib/solution/ScanOrder/index.js +862 -831
- package/lib/solution/ScanOrder/types.js +34 -33
- package/lib/solution/ScanOrder/utils.js +371 -406
- package/lib/solution/ShopDiscount/index.js +233 -235
- package/lib/solution/ShopDiscount/types.d.ts +4 -5
- package/lib/solution/ShopDiscount/types.js +37 -15
- package/lib/solution/ShopDiscount/utils.d.ts +0 -9
- package/lib/solution/ShopDiscount/utils.js +172 -309
- package/lib/solution/UnifiedBookingSales/index.js +405 -379
- package/lib/solution/UnifiedBookingSales/types.js +31 -12
- package/lib/solution/VenueBooking/index.d.ts +3 -31
- package/lib/solution/VenueBooking/index.js +916 -967
- package/lib/solution/VenueBooking/types.d.ts +1 -3
- package/lib/solution/VenueBooking/types.js +39 -20
- package/lib/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
- package/lib/solution/VenueBooking/utils/dateSummary.js +62 -25
- package/lib/solution/VenueBooking/utils/resource.js +54 -31
- package/lib/solution/VenueBooking/utils/slotMerge.js +107 -94
- package/lib/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
- package/lib/solution/VenueBooking/utils/timeSlot.js +133 -138
- package/lib/solution/VenueBooking/utils.js +67 -130
- package/lib/solution/index.js +41 -124
- package/lib/store/createStore.js +29 -32
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.js +16 -4
- package/lib/utils/task.js +36 -36
- package/lib/utils/watch.js +47 -81
- package/package.json +2 -4
- package/dist/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
- package/dist/solution/VenueBooking/utils/smartPricing.js +0 -233
- package/lib/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
- package/lib/solution/VenueBooking/utils/smartPricing.js +0 -192
|
@@ -1,52 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Object.
|
|
4
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
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);
|
|
18
|
+
|
|
19
|
+
// src/model/strategy/engine.ts
|
|
20
|
+
var engine_exports = {};
|
|
21
|
+
__export(engine_exports, {
|
|
22
|
+
StrategyEngine: () => StrategyEngine,
|
|
23
|
+
createStrategyEngine: () => createStrategyEngine,
|
|
24
|
+
evaluate: () => evaluate
|
|
5
25
|
});
|
|
6
|
-
exports
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var _type = require("./type");
|
|
10
|
-
/**
|
|
11
|
-
* 策略模型 - 核心实现
|
|
12
|
-
*
|
|
13
|
-
* 完全业务无关的通用策略引擎
|
|
14
|
-
* 支持条件评估、动作匹配、结果返回
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
// ============================================
|
|
18
|
-
// 策略引擎实现
|
|
19
|
-
// ============================================
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* 策略引擎
|
|
23
|
-
*
|
|
24
|
-
* 核心职责:
|
|
25
|
-
* 1. 递归评估条件组
|
|
26
|
-
* 2. 收集满足条件的 actionIds
|
|
27
|
-
* 3. 根据 actionIds 获取 ActionEffect 对象
|
|
28
|
-
* 4. 按 priority 排序返回
|
|
29
|
-
*/
|
|
30
|
-
class StrategyEngine {
|
|
31
|
-
options;
|
|
32
|
-
operatorHandlers;
|
|
26
|
+
module.exports = __toCommonJS(engine_exports);
|
|
27
|
+
var import_type = require("./type");
|
|
28
|
+
var StrategyEngine = class {
|
|
33
29
|
constructor(options = {}) {
|
|
34
30
|
this.options = {
|
|
35
31
|
debug: options.debug ?? false,
|
|
36
32
|
enableTrace: options.enableTrace ?? false,
|
|
37
33
|
operatorHandlers: options.operatorHandlers ?? {},
|
|
38
|
-
errorHandler: options.errorHandler ?? (error => console.error(error))
|
|
34
|
+
errorHandler: options.errorHandler ?? ((error) => console.error(error))
|
|
39
35
|
};
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
this.operatorHandlers = new Map(
|
|
37
|
+
Object.entries(this.options.operatorHandlers)
|
|
38
|
+
);
|
|
43
39
|
this.initializeBuiltInOperators();
|
|
44
40
|
}
|
|
45
|
-
|
|
46
41
|
/**
|
|
47
42
|
* 评估策略
|
|
48
43
|
*/
|
|
49
44
|
evaluate(config, context) {
|
|
45
|
+
var _a, _b;
|
|
50
46
|
const startTime = Date.now();
|
|
51
47
|
const trace = {
|
|
52
48
|
steps: [],
|
|
@@ -54,23 +50,23 @@ class StrategyEngine {
|
|
|
54
50
|
errors: []
|
|
55
51
|
};
|
|
56
52
|
try {
|
|
57
|
-
// 验证配置
|
|
58
53
|
this.validateConfig(config);
|
|
59
54
|
if (this.options.enableTrace) {
|
|
60
55
|
trace.steps.push({
|
|
61
|
-
step:
|
|
62
|
-
status:
|
|
56
|
+
step: "validate_config",
|
|
57
|
+
status: "success",
|
|
63
58
|
duration: Date.now() - startTime
|
|
64
59
|
});
|
|
65
60
|
}
|
|
66
|
-
|
|
67
|
-
// 递归评估条件组,收集 actionIds
|
|
68
61
|
const evaluateStart = Date.now();
|
|
69
|
-
const evaluationResult = this.evaluateConditionGroup(
|
|
62
|
+
const evaluationResult = this.evaluateConditionGroup(
|
|
63
|
+
config.conditions,
|
|
64
|
+
context
|
|
65
|
+
);
|
|
70
66
|
if (this.options.enableTrace) {
|
|
71
67
|
trace.steps.push({
|
|
72
|
-
step:
|
|
73
|
-
status:
|
|
68
|
+
step: "evaluate_conditions",
|
|
69
|
+
status: "success",
|
|
74
70
|
duration: Date.now() - evaluateStart,
|
|
75
71
|
details: {
|
|
76
72
|
satisfied: evaluationResult.satisfied,
|
|
@@ -78,51 +74,46 @@ class StrategyEngine {
|
|
|
78
74
|
}
|
|
79
75
|
});
|
|
80
76
|
}
|
|
81
|
-
|
|
82
|
-
// 根据 actionIds 获取 ActionEffect 对象
|
|
83
77
|
const actionStart = Date.now();
|
|
84
|
-
const matchedActions = this.getActionsByIds(
|
|
78
|
+
const matchedActions = this.getActionsByIds(
|
|
79
|
+
evaluationResult.actionIds,
|
|
80
|
+
config.actions
|
|
81
|
+
);
|
|
85
82
|
if (this.options.enableTrace) {
|
|
86
83
|
trace.steps.push({
|
|
87
|
-
step:
|
|
88
|
-
status:
|
|
84
|
+
step: "get_actions",
|
|
85
|
+
status: "success",
|
|
89
86
|
duration: Date.now() - actionStart,
|
|
90
|
-
details: {
|
|
91
|
-
matchedCount: matchedActions.length
|
|
92
|
-
}
|
|
87
|
+
details: { matchedCount: matchedActions.length }
|
|
93
88
|
});
|
|
94
89
|
}
|
|
95
|
-
|
|
96
|
-
// 按 priority 排序(降序)
|
|
97
90
|
const sortStart = Date.now();
|
|
98
91
|
const sortedActions = this.sortActionsByPriority(matchedActions);
|
|
99
92
|
if (this.options.enableTrace) {
|
|
100
93
|
trace.steps.push({
|
|
101
|
-
step:
|
|
102
|
-
status:
|
|
94
|
+
step: "sort_actions",
|
|
95
|
+
status: "success",
|
|
103
96
|
duration: Date.now() - sortStart
|
|
104
97
|
});
|
|
105
98
|
}
|
|
106
|
-
|
|
107
|
-
// 构建结果 - applicable 基于条件是否满足,而不是 actionIds 数量
|
|
108
99
|
const applicable = evaluationResult.satisfied;
|
|
109
100
|
const result = {
|
|
110
101
|
success: true,
|
|
111
102
|
applicable,
|
|
112
|
-
code: applicable ?
|
|
113
|
-
message: applicable ?
|
|
103
|
+
code: applicable ? import_type.SUCCESS_CODES.SUCCESS : import_type.NOT_APPLICABLE_CODES.CONDITION_NOT_MET,
|
|
104
|
+
message: applicable ? "Strategy is applicable" : "Conditions not met",
|
|
114
105
|
matched: {
|
|
115
106
|
conditions: applicable,
|
|
116
107
|
actionIds: evaluationResult.actionIds,
|
|
117
108
|
details: {},
|
|
118
|
-
...
|
|
119
|
-
failedField: evaluationResult.failedRules[0]
|
|
109
|
+
...applicable ? {} : {
|
|
110
|
+
failedField: (_a = evaluationResult.failedRules[0]) == null ? void 0 : _a.field,
|
|
120
111
|
failedRules: evaluationResult.failedRules
|
|
121
|
-
}
|
|
112
|
+
}
|
|
122
113
|
},
|
|
123
114
|
matchedActions: sortedActions,
|
|
124
115
|
outputs: {},
|
|
125
|
-
config
|
|
116
|
+
config
|
|
126
117
|
};
|
|
127
118
|
trace.duration = Date.now() - startTime;
|
|
128
119
|
if (this.options.enableTrace) {
|
|
@@ -130,10 +121,10 @@ class StrategyEngine {
|
|
|
130
121
|
}
|
|
131
122
|
return result;
|
|
132
123
|
} catch (error) {
|
|
133
|
-
const errorMessage = error instanceof Error ? error.message :
|
|
124
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
134
125
|
if (this.options.enableTrace) {
|
|
135
|
-
trace.errors
|
|
136
|
-
step:
|
|
126
|
+
(_b = trace.errors) == null ? void 0 : _b.push({
|
|
127
|
+
step: "evaluation",
|
|
137
128
|
error: errorMessage,
|
|
138
129
|
timestamp: Date.now()
|
|
139
130
|
});
|
|
@@ -143,7 +134,7 @@ class StrategyEngine {
|
|
|
143
134
|
return {
|
|
144
135
|
success: false,
|
|
145
136
|
applicable: false,
|
|
146
|
-
code:
|
|
137
|
+
code: import_type.ERROR_CODES.EVALUATION_ERROR,
|
|
147
138
|
message: errorMessage,
|
|
148
139
|
matched: {
|
|
149
140
|
conditions: false,
|
|
@@ -152,12 +143,11 @@ class StrategyEngine {
|
|
|
152
143
|
},
|
|
153
144
|
matchedActions: [],
|
|
154
145
|
outputs: {},
|
|
155
|
-
trace: this.options.enableTrace ? trace :
|
|
156
|
-
config
|
|
146
|
+
trace: this.options.enableTrace ? trace : void 0,
|
|
147
|
+
config
|
|
157
148
|
};
|
|
158
149
|
}
|
|
159
150
|
}
|
|
160
|
-
|
|
161
151
|
/**
|
|
162
152
|
* 递归评估条件组
|
|
163
153
|
*
|
|
@@ -167,16 +157,12 @@ class StrategyEngine {
|
|
|
167
157
|
*/
|
|
168
158
|
evaluateConditionGroup(group, context) {
|
|
169
159
|
const collectedActionIds = [];
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
failedRules
|
|
175
|
-
} = this.evaluateGroupLogicDetailed(group, context);
|
|
160
|
+
const { satisfied, failedRules } = this.evaluateGroupLogicDetailed(
|
|
161
|
+
group,
|
|
162
|
+
context
|
|
163
|
+
);
|
|
176
164
|
if (satisfied) {
|
|
177
165
|
collectedActionIds.push(...group.actionIds);
|
|
178
|
-
|
|
179
|
-
// 递归评估嵌套的 ConditionGroup,收集嵌套层的 actionIds
|
|
180
166
|
for (const rule of group.rules) {
|
|
181
167
|
if (this.isConditionGroup(rule)) {
|
|
182
168
|
const nestedResult = this.evaluateConditionGroup(rule, context);
|
|
@@ -190,7 +176,6 @@ class StrategyEngine {
|
|
|
190
176
|
failedRules
|
|
191
177
|
};
|
|
192
178
|
}
|
|
193
|
-
|
|
194
179
|
/**
|
|
195
180
|
* 评估条件组的逻辑运算(带失败规则收集)
|
|
196
181
|
*
|
|
@@ -200,72 +185,46 @@ class StrategyEngine {
|
|
|
200
185
|
* - `not`:被取反规则实际通过时,记录该规则
|
|
201
186
|
*/
|
|
202
187
|
evaluateGroupLogicDetailed(group, context) {
|
|
203
|
-
const {
|
|
204
|
-
operator,
|
|
205
|
-
rules
|
|
206
|
-
} = group;
|
|
188
|
+
const { operator, rules } = group;
|
|
207
189
|
switch (operator) {
|
|
208
|
-
case
|
|
209
|
-
{
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (!ruleResult.satisfied) {
|
|
213
|
-
return {
|
|
214
|
-
satisfied: false,
|
|
215
|
-
failedRules: ruleResult.failedRules
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
return {
|
|
220
|
-
satisfied: true,
|
|
221
|
-
failedRules: []
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
case 'or':
|
|
225
|
-
{
|
|
226
|
-
const aggregated = [];
|
|
227
|
-
for (const rule of rules) {
|
|
228
|
-
const ruleResult = this.evaluateRuleDetailed(rule, context);
|
|
229
|
-
if (ruleResult.satisfied) {
|
|
230
|
-
return {
|
|
231
|
-
satisfied: true,
|
|
232
|
-
failedRules: []
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
aggregated.push(...ruleResult.failedRules);
|
|
236
|
-
}
|
|
237
|
-
return {
|
|
238
|
-
satisfied: false,
|
|
239
|
-
failedRules: aggregated
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
case 'not':
|
|
243
|
-
{
|
|
244
|
-
if (rules.length === 0) {
|
|
190
|
+
case "and": {
|
|
191
|
+
for (const rule of rules) {
|
|
192
|
+
const ruleResult = this.evaluateRuleDetailed(rule, context);
|
|
193
|
+
if (!ruleResult.satisfied) {
|
|
245
194
|
return {
|
|
246
195
|
satisfied: false,
|
|
247
|
-
failedRules:
|
|
196
|
+
failedRules: ruleResult.failedRules
|
|
248
197
|
};
|
|
249
198
|
}
|
|
250
|
-
|
|
199
|
+
}
|
|
200
|
+
return { satisfied: true, failedRules: [] };
|
|
201
|
+
}
|
|
202
|
+
case "or": {
|
|
203
|
+
const aggregated = [];
|
|
204
|
+
for (const rule of rules) {
|
|
205
|
+
const ruleResult = this.evaluateRuleDetailed(rule, context);
|
|
251
206
|
if (ruleResult.satisfied) {
|
|
252
|
-
|
|
253
|
-
const failed = this.isConditionGroup(rules[0]) ? [] : [this.buildFailedRuleInfo(rules[0], context)];
|
|
254
|
-
return {
|
|
255
|
-
satisfied: false,
|
|
256
|
-
failedRules: failed
|
|
257
|
-
};
|
|
207
|
+
return { satisfied: true, failedRules: [] };
|
|
258
208
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
209
|
+
aggregated.push(...ruleResult.failedRules);
|
|
210
|
+
}
|
|
211
|
+
return { satisfied: false, failedRules: aggregated };
|
|
212
|
+
}
|
|
213
|
+
case "not": {
|
|
214
|
+
if (rules.length === 0) {
|
|
215
|
+
return { satisfied: false, failedRules: [] };
|
|
263
216
|
}
|
|
217
|
+
const ruleResult = this.evaluateRuleDetailed(rules[0], context);
|
|
218
|
+
if (ruleResult.satisfied) {
|
|
219
|
+
const failed = this.isConditionGroup(rules[0]) ? [] : [this.buildFailedRuleInfo(rules[0], context)];
|
|
220
|
+
return { satisfied: false, failedRules: failed };
|
|
221
|
+
}
|
|
222
|
+
return { satisfied: true, failedRules: [] };
|
|
223
|
+
}
|
|
264
224
|
default:
|
|
265
225
|
throw new Error(`Unknown operator: ${operator}`);
|
|
266
226
|
}
|
|
267
227
|
}
|
|
268
|
-
|
|
269
228
|
/**
|
|
270
229
|
* 评估单个规则(带失败规则收集)
|
|
271
230
|
*/
|
|
@@ -276,35 +235,27 @@ class StrategyEngine {
|
|
|
276
235
|
const conditionRule = rule;
|
|
277
236
|
const satisfied = this.evaluateAtomicRule(conditionRule, context);
|
|
278
237
|
if (satisfied) {
|
|
279
|
-
return {
|
|
280
|
-
satisfied: true,
|
|
281
|
-
failedRules: []
|
|
282
|
-
};
|
|
238
|
+
return { satisfied: true, failedRules: [] };
|
|
283
239
|
}
|
|
284
240
|
return {
|
|
285
241
|
satisfied: false,
|
|
286
242
|
failedRules: [this.buildFailedRuleInfo(conditionRule, context)]
|
|
287
243
|
};
|
|
288
244
|
}
|
|
289
|
-
|
|
290
245
|
/**
|
|
291
246
|
* 评估原子规则(不收集失败信息,仅返回布尔结果)
|
|
292
247
|
*/
|
|
293
248
|
evaluateAtomicRule(conditionRule, context) {
|
|
294
|
-
|
|
295
|
-
if (conditionRule.type === 'code' && conditionRule.code) {
|
|
249
|
+
if (conditionRule.type === "code" && conditionRule.code) {
|
|
296
250
|
return this.evaluateCodeCondition(conditionRule.code, context);
|
|
297
251
|
}
|
|
298
|
-
|
|
299
|
-
// Operator 模式:标准运算符判断
|
|
300
252
|
return this.evaluateOperatorCondition(conditionRule, context);
|
|
301
253
|
}
|
|
302
|
-
|
|
303
254
|
/**
|
|
304
255
|
* 构建失败规则信息
|
|
305
256
|
*/
|
|
306
257
|
buildFailedRuleInfo(conditionRule, context) {
|
|
307
|
-
const actualValue = conditionRule.field ? this.getFieldValue(conditionRule.field, context) :
|
|
258
|
+
const actualValue = conditionRule.field ? this.getFieldValue(conditionRule.field, context) : void 0;
|
|
308
259
|
return {
|
|
309
260
|
field: conditionRule.field,
|
|
310
261
|
operator: conditionRule.operator,
|
|
@@ -312,169 +263,144 @@ class StrategyEngine {
|
|
|
312
263
|
actualValue
|
|
313
264
|
};
|
|
314
265
|
}
|
|
315
|
-
|
|
316
266
|
/**
|
|
317
267
|
* 评估代码模式条件
|
|
318
268
|
*/
|
|
319
269
|
evaluateCodeCondition(code, context) {
|
|
320
270
|
try {
|
|
321
|
-
|
|
322
|
-
const
|
|
323
|
-
entities,
|
|
324
|
-
attributes,
|
|
325
|
-
metadata
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
// 使用 Function 构造器代替 eval,更安全
|
|
329
|
-
const evalFunc = new Function('entities', 'attributes', 'metadata', `return (${code})`);
|
|
271
|
+
const { entities, attributes, metadata } = context;
|
|
272
|
+
const evalFunc = new Function(
|
|
273
|
+
"entities",
|
|
274
|
+
"attributes",
|
|
275
|
+
"metadata",
|
|
276
|
+
`return (${code})`
|
|
277
|
+
);
|
|
330
278
|
const result = evalFunc(entities, attributes, metadata);
|
|
331
279
|
return Boolean(result);
|
|
332
280
|
} catch (error) {
|
|
333
281
|
if (this.options.debug) {
|
|
334
|
-
console.error(
|
|
282
|
+
console.error("Code evaluation error:", error);
|
|
335
283
|
}
|
|
336
284
|
return false;
|
|
337
285
|
}
|
|
338
286
|
}
|
|
339
|
-
|
|
340
287
|
/**
|
|
341
288
|
* 评估运算符模式条件
|
|
342
289
|
*/
|
|
343
290
|
evaluateOperatorCondition(rule, context) {
|
|
344
|
-
const {
|
|
345
|
-
field,
|
|
346
|
-
operator,
|
|
347
|
-
value
|
|
348
|
-
} = rule;
|
|
291
|
+
const { field, operator, value } = rule;
|
|
349
292
|
if (!field || !operator) {
|
|
350
293
|
return false;
|
|
351
294
|
}
|
|
352
|
-
|
|
353
|
-
// 从 context.attributes 中获取字段值
|
|
354
295
|
const fieldValue = this.getFieldValue(field, context);
|
|
355
|
-
|
|
356
|
-
// 使用运算符处理器
|
|
357
296
|
const handler = this.operatorHandlers.get(operator);
|
|
358
297
|
if (handler) {
|
|
359
298
|
return handler(fieldValue, value, rule);
|
|
360
299
|
}
|
|
361
|
-
|
|
362
|
-
// 回退到内置运算符
|
|
363
300
|
return this.evaluateBuiltInOperator(fieldValue, operator, value);
|
|
364
301
|
}
|
|
365
|
-
|
|
366
302
|
/**
|
|
367
303
|
* 获取字段值
|
|
368
304
|
*/
|
|
369
305
|
getFieldValue(field, context) {
|
|
370
|
-
|
|
371
|
-
const path = field.split('.');
|
|
306
|
+
const path = field.split(".");
|
|
372
307
|
let value = context.attributes;
|
|
373
308
|
for (const key of path) {
|
|
374
|
-
if (value && typeof value ===
|
|
309
|
+
if (value && typeof value === "object" && key in value) {
|
|
375
310
|
value = value[key];
|
|
376
311
|
} else {
|
|
377
|
-
return
|
|
312
|
+
return void 0;
|
|
378
313
|
}
|
|
379
314
|
}
|
|
380
315
|
return value;
|
|
381
316
|
}
|
|
382
|
-
|
|
383
317
|
/**
|
|
384
318
|
* 评估内置运算符
|
|
385
319
|
*/
|
|
386
320
|
evaluateBuiltInOperator(fieldValue, operator, compareValue) {
|
|
387
321
|
switch (operator) {
|
|
388
|
-
|
|
389
|
-
case
|
|
390
|
-
case '==':
|
|
322
|
+
case "=":
|
|
323
|
+
case "==":
|
|
391
324
|
return fieldValue == compareValue;
|
|
392
|
-
case
|
|
325
|
+
case "!=":
|
|
393
326
|
return fieldValue != compareValue;
|
|
394
|
-
case
|
|
327
|
+
case ">":
|
|
395
328
|
return fieldValue > compareValue;
|
|
396
|
-
case
|
|
329
|
+
case ">=":
|
|
397
330
|
return fieldValue >= compareValue;
|
|
398
|
-
case
|
|
331
|
+
case "<":
|
|
399
332
|
return fieldValue < compareValue;
|
|
400
|
-
case
|
|
333
|
+
case "<=":
|
|
401
334
|
return fieldValue <= compareValue;
|
|
402
|
-
|
|
403
|
-
// 集合运算符
|
|
404
|
-
case 'in':
|
|
335
|
+
case "in":
|
|
405
336
|
return Array.isArray(compareValue) && compareValue.includes(fieldValue);
|
|
406
|
-
case
|
|
337
|
+
case "not_in":
|
|
407
338
|
return Array.isArray(compareValue) && !compareValue.includes(fieldValue);
|
|
408
|
-
case
|
|
339
|
+
case "contains":
|
|
409
340
|
if (Array.isArray(fieldValue)) {
|
|
410
341
|
return fieldValue.includes(compareValue);
|
|
411
342
|
}
|
|
412
|
-
if (typeof fieldValue ===
|
|
343
|
+
if (typeof fieldValue === "string") {
|
|
413
344
|
return fieldValue.includes(compareValue);
|
|
414
345
|
}
|
|
415
346
|
return false;
|
|
416
|
-
case
|
|
347
|
+
case "not_contains":
|
|
417
348
|
if (Array.isArray(fieldValue)) {
|
|
418
349
|
return !fieldValue.includes(compareValue);
|
|
419
350
|
}
|
|
420
|
-
if (typeof fieldValue ===
|
|
351
|
+
if (typeof fieldValue === "string") {
|
|
421
352
|
return !fieldValue.includes(compareValue);
|
|
422
353
|
}
|
|
423
354
|
return true;
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
case
|
|
427
|
-
return typeof fieldValue ===
|
|
428
|
-
case
|
|
429
|
-
return typeof fieldValue ===
|
|
430
|
-
case
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
// 范围运算符
|
|
434
|
-
case 'between':
|
|
435
|
-
if (!Array.isArray(compareValue) || compareValue.length !== 2) return false;
|
|
355
|
+
case "starts_with":
|
|
356
|
+
return typeof fieldValue === "string" && fieldValue.startsWith(compareValue);
|
|
357
|
+
case "ends_with":
|
|
358
|
+
return typeof fieldValue === "string" && fieldValue.endsWith(compareValue);
|
|
359
|
+
case "regex":
|
|
360
|
+
return typeof fieldValue === "string" && new RegExp(compareValue).test(fieldValue);
|
|
361
|
+
case "between":
|
|
362
|
+
if (!Array.isArray(compareValue) || compareValue.length !== 2)
|
|
363
|
+
return false;
|
|
436
364
|
return fieldValue >= compareValue[0] && fieldValue <= compareValue[1];
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
case
|
|
440
|
-
return fieldValue
|
|
441
|
-
case
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
if (
|
|
445
|
-
|
|
446
|
-
if (typeof fieldValue ===
|
|
365
|
+
case "is_null":
|
|
366
|
+
return fieldValue === null || fieldValue === void 0;
|
|
367
|
+
case "is_not_null":
|
|
368
|
+
return fieldValue !== null && fieldValue !== void 0;
|
|
369
|
+
case "is_empty":
|
|
370
|
+
if (Array.isArray(fieldValue))
|
|
371
|
+
return fieldValue.length === 0;
|
|
372
|
+
if (typeof fieldValue === "string")
|
|
373
|
+
return fieldValue.length === 0;
|
|
374
|
+
if (typeof fieldValue === "object")
|
|
375
|
+
return Object.keys(fieldValue).length === 0;
|
|
447
376
|
return !fieldValue;
|
|
448
|
-
case
|
|
449
|
-
if (Array.isArray(fieldValue))
|
|
450
|
-
|
|
451
|
-
if (typeof fieldValue ===
|
|
377
|
+
case "is_not_empty":
|
|
378
|
+
if (Array.isArray(fieldValue))
|
|
379
|
+
return fieldValue.length > 0;
|
|
380
|
+
if (typeof fieldValue === "string")
|
|
381
|
+
return fieldValue.length > 0;
|
|
382
|
+
if (typeof fieldValue === "object")
|
|
383
|
+
return Object.keys(fieldValue).length > 0;
|
|
452
384
|
return Boolean(fieldValue);
|
|
453
|
-
|
|
454
|
-
// 商品匹配运算符
|
|
455
|
-
case 'product_match':
|
|
385
|
+
case "product_match":
|
|
456
386
|
return this.evaluateProductMatch(fieldValue, compareValue);
|
|
457
|
-
|
|
458
|
-
// 对象包含运算符(兼容旧配置)
|
|
459
|
-
case 'object_in':
|
|
387
|
+
case "object_in":
|
|
460
388
|
return this.evaluateProductMatch(fieldValue, compareValue);
|
|
461
389
|
default:
|
|
462
390
|
throw new Error(`Unsupported operator: ${operator}`);
|
|
463
391
|
}
|
|
464
392
|
}
|
|
465
|
-
|
|
466
393
|
/**
|
|
467
394
|
* 根据 actionIds 获取 ActionEffect 对象
|
|
468
395
|
*/
|
|
469
396
|
getActionsByIds(actionIds, actions) {
|
|
470
397
|
const matchedActions = [];
|
|
471
|
-
const actionMap = new Map(actions.map(action => [action.id, action]));
|
|
398
|
+
const actionMap = new Map(actions.map((action) => [action.id, action]));
|
|
472
399
|
for (const id of actionIds) {
|
|
473
400
|
const action = actionMap.get(id);
|
|
474
401
|
if (action) {
|
|
475
402
|
matchedActions.push(action);
|
|
476
403
|
} else {
|
|
477
|
-
// 找不到的 ID 记录警告
|
|
478
404
|
if (this.options.debug) {
|
|
479
405
|
console.warn(`Action with id "${id}" not found in actions array`);
|
|
480
406
|
}
|
|
@@ -482,7 +408,6 @@ class StrategyEngine {
|
|
|
482
408
|
}
|
|
483
409
|
return matchedActions;
|
|
484
410
|
}
|
|
485
|
-
|
|
486
411
|
/**
|
|
487
412
|
* 按 priority 排序(降序)
|
|
488
413
|
*/
|
|
@@ -490,43 +415,37 @@ class StrategyEngine {
|
|
|
490
415
|
return [...actions].sort((a, b) => {
|
|
491
416
|
const priorityA = a.priority ?? 0;
|
|
492
417
|
const priorityB = b.priority ?? 0;
|
|
493
|
-
return priorityB - priorityA;
|
|
418
|
+
return priorityB - priorityA;
|
|
494
419
|
});
|
|
495
420
|
}
|
|
496
|
-
|
|
497
421
|
/**
|
|
498
422
|
* 判断是否为条件组
|
|
499
423
|
*/
|
|
500
424
|
isConditionGroup(rule) {
|
|
501
|
-
return
|
|
425
|
+
return "operator" in rule && "rules" in rule && Array.isArray(rule.rules);
|
|
502
426
|
}
|
|
503
|
-
|
|
504
427
|
/**
|
|
505
428
|
* 验证配置
|
|
506
429
|
*/
|
|
507
430
|
validateConfig(config) {
|
|
508
431
|
if (!config) {
|
|
509
|
-
throw new Error(
|
|
432
|
+
throw new Error("Strategy config is required");
|
|
510
433
|
}
|
|
511
434
|
if (!config.metadata || !config.metadata.id) {
|
|
512
|
-
throw new Error(
|
|
435
|
+
throw new Error("Strategy metadata.id is required");
|
|
513
436
|
}
|
|
514
437
|
if (!config.conditions) {
|
|
515
|
-
throw new Error(
|
|
438
|
+
throw new Error("Strategy conditions is required");
|
|
516
439
|
}
|
|
517
440
|
if (!Array.isArray(config.actions)) {
|
|
518
|
-
throw new Error(
|
|
441
|
+
throw new Error("Strategy actions must be an array");
|
|
519
442
|
}
|
|
520
443
|
}
|
|
521
|
-
|
|
522
444
|
/**
|
|
523
445
|
* 初始化内置运算符处理器
|
|
524
446
|
*/
|
|
525
447
|
initializeBuiltInOperators() {
|
|
526
|
-
// 内置运算符已经在 evaluateBuiltInOperator 中实现
|
|
527
|
-
// 这里可以添加自定义的运算符处理器
|
|
528
448
|
}
|
|
529
|
-
|
|
530
449
|
/**
|
|
531
450
|
* 评估商品匹配运算符
|
|
532
451
|
*
|
|
@@ -540,49 +459,35 @@ class StrategyEngine {
|
|
|
540
459
|
* @returns 是否匹配
|
|
541
460
|
*/
|
|
542
461
|
evaluateProductMatch(fieldValue, configValue) {
|
|
543
|
-
// 确保 configValue 是数组
|
|
544
462
|
if (!Array.isArray(configValue)) {
|
|
545
463
|
return false;
|
|
546
464
|
}
|
|
547
|
-
|
|
548
|
-
// 确保 fieldValue 是有效的商品对象
|
|
549
|
-
if (!fieldValue || typeof fieldValue !== 'object' || typeof fieldValue.product_id !== 'number') {
|
|
465
|
+
if (!fieldValue || typeof fieldValue !== "object" || typeof fieldValue.product_id !== "number") {
|
|
550
466
|
return false;
|
|
551
467
|
}
|
|
552
468
|
const actualProductId = fieldValue.product_id;
|
|
553
469
|
const actualVariantId = fieldValue.product_variant_id ?? 0;
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
return configValue.some(item => {
|
|
557
|
-
// 验证配置项格式
|
|
558
|
-
if (!item || typeof item.product_id !== 'number') {
|
|
470
|
+
return configValue.some((item) => {
|
|
471
|
+
if (!item || typeof item.product_id !== "number") {
|
|
559
472
|
return false;
|
|
560
473
|
}
|
|
561
474
|
const configProductId = item.product_id;
|
|
562
475
|
const configVariantId = item.product_variant_id ?? 0;
|
|
563
|
-
|
|
564
|
-
// 首先检查 product_id 是否匹配
|
|
565
476
|
if (configProductId !== actualProductId) {
|
|
566
477
|
return false;
|
|
567
478
|
}
|
|
568
|
-
|
|
569
|
-
// 如果配置的 product_variant_id = 0,只需要 product_id 匹配
|
|
570
479
|
if (configVariantId === 0) {
|
|
571
480
|
return true;
|
|
572
481
|
}
|
|
573
|
-
|
|
574
|
-
// 否则需要 product_variant_id 精确匹配
|
|
575
482
|
return configVariantId === actualVariantId;
|
|
576
483
|
});
|
|
577
484
|
}
|
|
578
|
-
|
|
579
485
|
/**
|
|
580
486
|
* 注册自定义运算符
|
|
581
487
|
*/
|
|
582
488
|
registerOperator(operator, handler) {
|
|
583
489
|
this.operatorHandlers.set(operator, handler);
|
|
584
490
|
}
|
|
585
|
-
|
|
586
491
|
/**
|
|
587
492
|
* 获取调试信息
|
|
588
493
|
*/
|
|
@@ -593,24 +498,17 @@ class StrategyEngine {
|
|
|
593
498
|
registeredOperators: Array.from(this.operatorHandlers.keys())
|
|
594
499
|
};
|
|
595
500
|
}
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
// ============================================
|
|
599
|
-
// 导出工具函数
|
|
600
|
-
// ============================================
|
|
601
|
-
|
|
602
|
-
/**
|
|
603
|
-
* 创建策略引擎实例
|
|
604
|
-
*/
|
|
605
|
-
exports.StrategyEngine = StrategyEngine;
|
|
501
|
+
};
|
|
606
502
|
function createStrategyEngine(options) {
|
|
607
503
|
return new StrategyEngine(options);
|
|
608
504
|
}
|
|
609
|
-
|
|
610
|
-
/**
|
|
611
|
-
* 快速评估(使用默认引擎配置)
|
|
612
|
-
*/
|
|
613
505
|
function evaluate(config, context) {
|
|
614
506
|
const engine = new StrategyEngine();
|
|
615
507
|
return engine.evaluate(config, context);
|
|
616
|
-
}
|
|
508
|
+
}
|
|
509
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
510
|
+
0 && (module.exports = {
|
|
511
|
+
StrategyEngine,
|
|
512
|
+
createStrategyEngine,
|
|
513
|
+
evaluate
|
|
514
|
+
});
|