@pisell/pisellos 2.1.170 → 2.1.171
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/model/strategy/adapter/dataVariant/evaluator.js +13 -100
- package/dist/model/strategy/adapter/dataVariant/type.d.ts +0 -1
- package/dist/model/strategy/adapter/promotion/index.js +0 -9
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/VenueBooking/index.d.ts +10 -0
- package/dist/solution/VenueBooking/index.js +421 -199
- package/dist/solution/VenueBooking/utils/smartPricing.d.ts +0 -1
- package/dist/solution/VenueBooking/utils/smartPricing.js +9 -78
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +8 -91
- package/lib/model/strategy/adapter/dataVariant/type.d.ts +0 -1
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/VenueBooking/index.d.ts +10 -0
- package/lib/solution/VenueBooking/index.js +272 -82
- package/lib/solution/VenueBooking/utils/smartPricing.d.ts +0 -1
- package/lib/solution/VenueBooking/utils/smartPricing.js +1 -46
- package/package.json +1 -1
|
@@ -220,6 +220,45 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
220
220
|
};
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
|
+
getOrderPricingSnapshotForDiagnostics() {
|
|
224
|
+
var _a, _b;
|
|
225
|
+
try {
|
|
226
|
+
const products = (_b = (_a = this.store.order) == null ? void 0 : _a.getTempOrder()) == null ? void 0 : _b.products;
|
|
227
|
+
if (!Array.isArray(products))
|
|
228
|
+
return [];
|
|
229
|
+
return products.map((product) => {
|
|
230
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
231
|
+
return {
|
|
232
|
+
productId: product == null ? void 0 : product.product_id,
|
|
233
|
+
resourceId: (_a2 = product == null ? void 0 : product.metadata) == null ? void 0 : _a2.resource_id,
|
|
234
|
+
isVenueBooking: !!((_b2 = product == null ? void 0 : product.metadata) == null ? void 0 : _b2.venue_booking),
|
|
235
|
+
sellingPrice: product == null ? void 0 : product.selling_price,
|
|
236
|
+
originalPrice: product == null ? void 0 : product.original_price,
|
|
237
|
+
sourceProductPrice: (_c = product == null ? void 0 : product.metadata) == null ? void 0 : _c.source_product_price,
|
|
238
|
+
mainProductOriginalPrice: (_d = product == null ? void 0 : product.metadata) == null ? void 0 : _d.main_product_original_price,
|
|
239
|
+
mainProductSellingPrice: (_e = product == null ? void 0 : product.metadata) == null ? void 0 : _e.main_product_selling_price,
|
|
240
|
+
priceBreakdown: (_f = product == null ? void 0 : product.metadata) == null ? void 0 : _f.price_breakdown,
|
|
241
|
+
discountList: product == null ? void 0 : product.discount_list
|
|
242
|
+
};
|
|
243
|
+
});
|
|
244
|
+
} catch (error) {
|
|
245
|
+
return [{ readFailed: true, error: this.serializeError(error) }];
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
getCatalogPricingSnapshotForDiagnostics() {
|
|
249
|
+
const orderProductIds = new Set(
|
|
250
|
+
this.getOrderPricingSnapshotForDiagnostics().map((product) => Number(product.productId)).filter((productId) => Number.isFinite(productId))
|
|
251
|
+
);
|
|
252
|
+
return this.getAllProductsForSmartPricing().filter((product) => orderProductIds.has(Number(product == null ? void 0 : product.id))).map((product) => ({
|
|
253
|
+
productId: product == null ? void 0 : product.id,
|
|
254
|
+
price: product == null ? void 0 : product.price,
|
|
255
|
+
sellingPrice: product == null ? void 0 : product.selling_price,
|
|
256
|
+
dataVariants: Array.isArray(product == null ? void 0 : product.data_variants) ? product.data_variants.map((variant) => ({
|
|
257
|
+
ruleId: variant == null ? void 0 : variant.data_variant_rule_id,
|
|
258
|
+
data: variant == null ? void 0 : variant.data
|
|
259
|
+
})) : []
|
|
260
|
+
}));
|
|
261
|
+
}
|
|
223
262
|
logMethodStart(method, payload = {}) {
|
|
224
263
|
void this.addVenueBookingLog({
|
|
225
264
|
level: "info",
|
|
@@ -310,18 +349,8 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
310
349
|
this.clearLoginEffectListeners();
|
|
311
350
|
const createHandleLogin = () => async (payload) => {
|
|
312
351
|
const customerId = this.resolveCustomerIdFromLoginPayload(payload);
|
|
313
|
-
|
|
314
|
-
customerId,
|
|
315
|
-
hasLoadAllProductsInFlight: !!this.loadAllProductsInFlight,
|
|
316
|
-
productsLoaded: this.productsLoaded,
|
|
317
|
-
smartPricingProductCatalogCount: this.smartPricingProductCatalog.length
|
|
318
|
-
});
|
|
319
|
-
if (!customerId) {
|
|
320
|
-
this.logPricingDiagnostics(
|
|
321
|
-
"[VenueBooking] customer login event skipped customerId not found in login payload"
|
|
322
|
-
);
|
|
352
|
+
if (!customerId)
|
|
323
353
|
return;
|
|
324
|
-
}
|
|
325
354
|
await this.refreshOrderMarketingAfterLogin({ customerId });
|
|
326
355
|
};
|
|
327
356
|
this.registerLoginEffect(_VenueBookingImpl.PISELL1_LOGIN_SUCCESS, createHandleLogin());
|
|
@@ -331,21 +360,20 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
331
360
|
async refreshOrderMarketingAfterLogin(params) {
|
|
332
361
|
if (!this.store.order)
|
|
333
362
|
throw new Error("order 模块未初始化");
|
|
334
|
-
this.
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
363
|
+
const pricingDiagnosticsEnabled = this.isPricingDiagnosticsEnabled();
|
|
364
|
+
if (pricingDiagnosticsEnabled) {
|
|
365
|
+
this.logPricingDiagnostics("[VenueBooking] refreshOrderMarketingAfterLogin entered", {
|
|
366
|
+
customerId: params.customerId,
|
|
367
|
+
hasCustomerLoginRefreshInFlight: !!this.customerLoginRefreshInFlight,
|
|
368
|
+
customerLoginRefreshIdInFlight: this.customerLoginRefreshIdInFlight,
|
|
369
|
+
hasLoadAllProductsInFlight: !!this.loadAllProductsInFlight,
|
|
370
|
+
productsLoaded: this.productsLoaded,
|
|
371
|
+
smartPricingProductCatalogCount: this.smartPricingProductCatalog.length,
|
|
372
|
+
note: "This login refresh reloads products with the confirmed customer context before recalculation"
|
|
373
|
+
});
|
|
374
|
+
}
|
|
343
375
|
if (this.customerLoginRefreshInFlight) {
|
|
344
376
|
if (this.customerLoginRefreshIdInFlight === params.customerId) {
|
|
345
|
-
this.logPricingDiagnostics("[VenueBooking] customer login refresh reused", {
|
|
346
|
-
customerId: params.customerId,
|
|
347
|
-
reason: "same customer refresh is already in flight"
|
|
348
|
-
});
|
|
349
377
|
await this.customerLoginRefreshInFlight;
|
|
350
378
|
return;
|
|
351
379
|
}
|
|
@@ -353,29 +381,139 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
353
381
|
}
|
|
354
382
|
this.customerLoginRefreshIdInFlight = params.customerId;
|
|
355
383
|
const refreshTask = (async () => {
|
|
356
|
-
var _a, _b, _c;
|
|
384
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
357
385
|
this.smartPricingCustomerId = params.customerId;
|
|
386
|
+
if (pricingDiagnosticsEnabled) {
|
|
387
|
+
this.logPricingDiagnostics("[VenueBooking] login pricing customer context set", {
|
|
388
|
+
customerId: params.customerId,
|
|
389
|
+
userPluginCustomerId: this.resolveCustomerIdForSmartPricing(),
|
|
390
|
+
availableWalletIdsBeforeDiscountConfig: this.getAvailableWalletIdsForDiagnostics(),
|
|
391
|
+
orderProductsBeforeDiscountConfig: this.getOrderPricingSnapshotForDiagnostics()
|
|
392
|
+
});
|
|
393
|
+
}
|
|
358
394
|
await this.store.order.loadDiscountConfig({
|
|
359
395
|
customerId: params.customerId
|
|
360
396
|
});
|
|
397
|
+
if (pricingDiagnosticsEnabled) {
|
|
398
|
+
const productsLoadBeforeLogin = this.loadAllProductsInFlight;
|
|
399
|
+
if (productsLoadBeforeLogin) {
|
|
400
|
+
this.logPricingDiagnostics("[VenueBooking] login waiting for previous product load", {
|
|
401
|
+
customerId: params.customerId
|
|
402
|
+
});
|
|
403
|
+
try {
|
|
404
|
+
await productsLoadBeforeLogin;
|
|
405
|
+
} catch (error) {
|
|
406
|
+
this.logPricingDiagnostics("[VenueBooking] previous product load failed before login reload", {
|
|
407
|
+
customerId: params.customerId,
|
|
408
|
+
error: this.serializeError(error)
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
this.logPricingDiagnostics("[VenueBooking] login product reload starting", {
|
|
413
|
+
customerId: params.customerId,
|
|
414
|
+
productsLoadedBeforeReload: this.productsLoaded,
|
|
415
|
+
catalogCountBeforeReload: this.smartPricingProductCatalog.length,
|
|
416
|
+
availableWalletIds: this.getAvailableWalletIdsForDiagnostics()
|
|
417
|
+
});
|
|
418
|
+
const loginProducts = await this.loadAllProducts();
|
|
419
|
+
this.logPricingDiagnostics("[VenueBooking] login product reload completed", {
|
|
420
|
+
customerId: params.customerId,
|
|
421
|
+
venueProductCount: loginProducts.venueProducts.length,
|
|
422
|
+
addonProductCount: loginProducts.addonProducts.length,
|
|
423
|
+
catalogCountAfterReload: this.smartPricingProductCatalog.length,
|
|
424
|
+
resourceProductMapSize: this.resourceProductMap.size
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
if (pricingDiagnosticsEnabled) {
|
|
428
|
+
const smartPricingContext = this.buildSmartPricingContext();
|
|
429
|
+
const strategyConfigs = ((_b = (_a = smartPricingContext.evaluator) == null ? void 0 : _a.getStrategyConfigs) == null ? void 0 : _b.call(_a)) || [];
|
|
430
|
+
this.logPricingDiagnostics("[VenueBooking] login discount config loaded", {
|
|
431
|
+
customerId: params.customerId,
|
|
432
|
+
availableWalletIdsAfterDiscountConfig: this.getAvailableWalletIdsForDiagnostics(),
|
|
433
|
+
discountList: this.store.order.getDiscountList(),
|
|
434
|
+
smartPricingContext: {
|
|
435
|
+
customerId: smartPricingContext.customerId,
|
|
436
|
+
availableWalletIds: smartPricingContext.availableWalletIds,
|
|
437
|
+
channel: smartPricingContext.channel,
|
|
438
|
+
businessCode: smartPricingContext.businessCode,
|
|
439
|
+
orderType: smartPricingContext.orderType,
|
|
440
|
+
scheduleCount: ((_c = smartPricingContext.scheduleList) == null ? void 0 : _c.length) || 0,
|
|
441
|
+
menuCount: ((_d = smartPricingContext.menuList) == null ? void 0 : _d.length) || 0,
|
|
442
|
+
hasEvaluator: !!smartPricingContext.evaluator
|
|
443
|
+
},
|
|
444
|
+
strategyConfigs: strategyConfigs.map((config) => {
|
|
445
|
+
var _a2, _b2, _c2, _d2, _e2, _f2;
|
|
446
|
+
return {
|
|
447
|
+
ruleId: (_a2 = config == null ? void 0 : config.metadata) == null ? void 0 : _a2.id,
|
|
448
|
+
name: (_b2 = config == null ? void 0 : config.metadata) == null ? void 0 : _b2.name,
|
|
449
|
+
status: (_d2 = (_c2 = config == null ? void 0 : config.metadata) == null ? void 0 : _c2.custom) == null ? void 0 : _d2.status,
|
|
450
|
+
priority: (_f2 = (_e2 = config == null ? void 0 : config.metadata) == null ? void 0 : _e2.custom) == null ? void 0 : _f2.priority,
|
|
451
|
+
conditions: config == null ? void 0 : config.conditions
|
|
452
|
+
};
|
|
453
|
+
}),
|
|
454
|
+
productsLoaded: this.productsLoaded,
|
|
455
|
+
smartPricingProductCatalogCount: (_e = this.smartPricingProductCatalog) == null ? void 0 : _e.length,
|
|
456
|
+
resourceProductMapSize: this.resourceProductMap.size,
|
|
457
|
+
matchingCatalogProducts: this.getCatalogPricingSnapshotForDiagnostics()
|
|
458
|
+
});
|
|
459
|
+
}
|
|
361
460
|
this.clearSlotPriceMapCache();
|
|
461
|
+
if (pricingDiagnosticsEnabled) {
|
|
462
|
+
this.logPricingDiagnostics("[VenueBooking] login smart pricing recalculation starting", {
|
|
463
|
+
slotPriceMapCacheSizeAfterClear: this.slotPriceMapCache.size,
|
|
464
|
+
orderProductsBeforeRecalculation: this.getOrderPricingSnapshotForDiagnostics()
|
|
465
|
+
});
|
|
466
|
+
}
|
|
362
467
|
this.recalculateOrderPricesFromSmartPricing();
|
|
468
|
+
if (pricingDiagnosticsEnabled) {
|
|
469
|
+
this.logPricingDiagnostics("[VenueBooking] login smart pricing recalculation completed", {
|
|
470
|
+
orderProductsAfterRecalculation: this.getOrderPricingSnapshotForDiagnostics()
|
|
471
|
+
});
|
|
472
|
+
}
|
|
363
473
|
this.store.order.applyDiscount();
|
|
364
474
|
this.normalizeDiscountedOrderPrices(
|
|
365
475
|
this.store.order.getDiscountList()
|
|
366
476
|
);
|
|
477
|
+
if (pricingDiagnosticsEnabled) {
|
|
478
|
+
this.logPricingDiagnostics("[VenueBooking] login discounts reapplied", {
|
|
479
|
+
discountList: this.store.order.getDiscountList(),
|
|
480
|
+
orderProductsAfterDiscount: this.getOrderPricingSnapshotForDiagnostics()
|
|
481
|
+
});
|
|
482
|
+
}
|
|
367
483
|
await this.store.order.recalculateSummary({ createIfMissing: true });
|
|
368
484
|
this.store.order.persistTempOrder();
|
|
485
|
+
if (pricingDiagnosticsEnabled) {
|
|
486
|
+
this.logPricingDiagnostics("[VenueBooking] login pricing summary persisted", {
|
|
487
|
+
summary: (_f = this.store.order.getTempOrder()) == null ? void 0 : _f.summary,
|
|
488
|
+
orderProducts: this.getOrderPricingSnapshotForDiagnostics()
|
|
489
|
+
});
|
|
490
|
+
}
|
|
369
491
|
await this.refreshItemRuleQuantityLimits();
|
|
370
492
|
await this.refreshCartValidationPassed();
|
|
371
|
-
await ((
|
|
493
|
+
await ((_i = (_h = (_g = this.core) == null ? void 0 : _g.effects) == null ? void 0 : _h.emit) == null ? void 0 : _i.call(_h, import_types.VenueBookingHooks.onSmartPricingUpdated, {
|
|
372
494
|
customerId: params.customerId
|
|
373
495
|
}));
|
|
496
|
+
if (pricingDiagnosticsEnabled) {
|
|
497
|
+
this.logPricingDiagnostics("[VenueBooking] login smart pricing update emitted", {
|
|
498
|
+
customerId: params.customerId,
|
|
499
|
+
cartValidation: this.store.cartValidation
|
|
500
|
+
});
|
|
501
|
+
}
|
|
374
502
|
})();
|
|
375
503
|
this.customerLoginRefreshInFlight = refreshTask;
|
|
376
504
|
try {
|
|
377
505
|
await refreshTask;
|
|
378
506
|
} catch (error) {
|
|
507
|
+
if (pricingDiagnosticsEnabled) {
|
|
508
|
+
this.logPricingDiagnostics("[VenueBooking] login smart pricing refresh failed", {
|
|
509
|
+
customerId: params.customerId,
|
|
510
|
+
error: this.serializeError(error),
|
|
511
|
+
productsLoaded: this.productsLoaded,
|
|
512
|
+
smartPricingProductCatalogCount: this.smartPricingProductCatalog.length,
|
|
513
|
+
resourceProductMapSize: this.resourceProductMap.size,
|
|
514
|
+
orderProducts: this.getOrderPricingSnapshotForDiagnostics()
|
|
515
|
+
});
|
|
516
|
+
}
|
|
379
517
|
throw error;
|
|
380
518
|
} finally {
|
|
381
519
|
if (this.customerLoginRefreshInFlight === refreshTask) {
|
|
@@ -402,12 +540,6 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
402
540
|
this.store.slotConfig = { ...this.baseSlotConfig };
|
|
403
541
|
this.otherParams = options.otherParams || {};
|
|
404
542
|
this.cacheId = (_c = this.otherParams) == null ? void 0 : _c.cacheId;
|
|
405
|
-
this.logPricingDiagnostics("[VenueBooking] initialize product loading state", {
|
|
406
|
-
hasLoadAllProductsInFlight: !!this.loadAllProductsInFlight,
|
|
407
|
-
productsLoaded: this.productsLoaded,
|
|
408
|
-
smartPricingProductCatalogCount: this.smartPricingProductCatalog.length,
|
|
409
|
-
note: "initialize currently does not reset the product loading state"
|
|
410
|
-
});
|
|
411
543
|
this.itemRuleRuntimeConfig = ((_d = this.otherParams) == null ? void 0 : _d.venueBookingItemRule) || ((_e = this.otherParams) == null ? void 0 : _e.itemRule) || {};
|
|
412
544
|
this.itemRuleConfigs = [];
|
|
413
545
|
this.itemRuleConfigsPromise = null;
|
|
@@ -650,10 +782,7 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
650
782
|
channel: (_f = this.otherParams) == null ? void 0 : _f.channel,
|
|
651
783
|
businessCode: (_g = this.otherParams) == null ? void 0 : _g.businessCode,
|
|
652
784
|
orderType: ((_h = this.otherParams) == null ? void 0 : _h.orderType) || ((_i = this.otherParams) == null ? void 0 : _i.type),
|
|
653
|
-
strategy_context: (_j = this.otherParams) == null ? void 0 : _j.strategy_context
|
|
654
|
-
...this.isPricingDiagnosticsEnabled() ? {
|
|
655
|
-
debugLog: (title, payload = {}) => this.logPricingDiagnostics(title, payload)
|
|
656
|
-
} : {}
|
|
785
|
+
strategy_context: (_j = this.otherParams) == null ? void 0 : _j.strategy_context
|
|
657
786
|
};
|
|
658
787
|
}
|
|
659
788
|
/** venue + addon 全量商品,供智能定价评估 */
|
|
@@ -697,30 +826,9 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
697
826
|
}
|
|
698
827
|
// ─── 场地商品 & 附加商品 ───
|
|
699
828
|
async loadAllProducts() {
|
|
700
|
-
this.
|
|
701
|
-
hasLoadAllProductsInFlight: !!this.loadAllProductsInFlight,
|
|
702
|
-
productsLoaded: this.productsLoaded,
|
|
703
|
-
smartPricingCustomerId: this.smartPricingCustomerId,
|
|
704
|
-
smartPricingProductCatalogCount: this.smartPricingProductCatalog.length,
|
|
705
|
-
venueProducts: !this.store.venueProducts,
|
|
706
|
-
addonProducts: !this.store.addonProducts
|
|
707
|
-
});
|
|
708
|
-
if (this.loadAllProductsInFlight) {
|
|
709
|
-
this.logPricingDiagnostics("[VenueBooking] loadAllProducts request skipped", {
|
|
710
|
-
reason: "reusing existing loadAllProductsInFlight promise",
|
|
711
|
-
productsLoaded: this.productsLoaded
|
|
712
|
-
});
|
|
829
|
+
if (this.loadAllProductsInFlight)
|
|
713
830
|
return this.loadAllProductsInFlight;
|
|
714
|
-
}
|
|
715
|
-
this.logPricingDiagnostics("[VenueBooking] loadAllProducts request starting", {
|
|
716
|
-
productsLoaded: this.productsLoaded,
|
|
717
|
-
smartPricingCustomerId: this.smartPricingCustomerId
|
|
718
|
-
});
|
|
719
831
|
this.loadAllProductsInFlight = this._doLoadAllProducts().finally(() => {
|
|
720
|
-
this.logPricingDiagnostics("[VenueBooking] loadAllProducts request settled", {
|
|
721
|
-
productsLoaded: this.productsLoaded,
|
|
722
|
-
smartPricingProductCatalogCount: this.smartPricingProductCatalog.length
|
|
723
|
-
});
|
|
724
832
|
this.loadAllProductsInFlight = null;
|
|
725
833
|
});
|
|
726
834
|
return this.loadAllProductsInFlight;
|
|
@@ -750,21 +858,11 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
750
858
|
const rawList = Array.isArray(allProducts) ? allProducts : [];
|
|
751
859
|
let list = rawList;
|
|
752
860
|
this.smartPricingProductCatalog = rawList.slice();
|
|
753
|
-
const smartPricingContext = this.buildSmartPricingContext();
|
|
754
861
|
list = (0, import_smartPricing.formatProductsWithDataVariant)(
|
|
755
862
|
list,
|
|
756
|
-
|
|
863
|
+
this.buildSmartPricingContext(),
|
|
757
864
|
(0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
|
|
758
865
|
);
|
|
759
|
-
if (this.isPricingDiagnosticsEnabled()) {
|
|
760
|
-
this.logPricingDiagnostics("[VenueBooking] loadAllProducts smart pricing context", {
|
|
761
|
-
smartPricingContext,
|
|
762
|
-
rawList,
|
|
763
|
-
list,
|
|
764
|
-
otherParams: this.otherParams,
|
|
765
|
-
availableWalletIds: this.getAvailableWalletIdsForDiagnostics()
|
|
766
|
-
});
|
|
767
|
-
}
|
|
768
866
|
this.clearSlotPriceMapCache();
|
|
769
867
|
const venueList = list.filter((p) => p.duration != null);
|
|
770
868
|
const addonList = list.filter((p) => p.duration == null);
|
|
@@ -788,10 +886,6 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
788
886
|
}
|
|
789
887
|
}
|
|
790
888
|
async loadVenueProducts() {
|
|
791
|
-
this.logPricingDiagnostics("[VenueBooking] loadVenueProducts called", {
|
|
792
|
-
hasLoadAllProductsInFlight: !!this.loadAllProductsInFlight,
|
|
793
|
-
productsLoaded: this.productsLoaded
|
|
794
|
-
});
|
|
795
889
|
const result = await this.loadAllProducts();
|
|
796
890
|
return result.venueProducts;
|
|
797
891
|
}
|
|
@@ -1389,24 +1483,60 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1389
1483
|
throw error;
|
|
1390
1484
|
}
|
|
1391
1485
|
}
|
|
1486
|
+
/**
|
|
1487
|
+
* 接收 pisell2 VenueBooking 登录链路诊断日志。
|
|
1488
|
+
* 实际是否上报仍由 OS 内部 cacheId 白名单统一控制。
|
|
1489
|
+
*/
|
|
1490
|
+
logPricingDiagnosticsFromClient(params) {
|
|
1491
|
+
this.logPricingDiagnostics(
|
|
1492
|
+
`[VenueBooking][pisell2] ${String((params == null ? void 0 : params.title) || "diagnostic")}`,
|
|
1493
|
+
(params == null ? void 0 : params.payload) || {}
|
|
1494
|
+
);
|
|
1495
|
+
}
|
|
1392
1496
|
recalculateOrderPricesFromSmartPricing() {
|
|
1393
1497
|
var _a, _b;
|
|
1394
|
-
if (!this.store.order)
|
|
1498
|
+
if (!this.store.order) {
|
|
1499
|
+
this.logPricingDiagnostics("[VenueBooking] order smart pricing recalculation skipped", {
|
|
1500
|
+
reason: "order module is missing"
|
|
1501
|
+
});
|
|
1395
1502
|
return;
|
|
1503
|
+
}
|
|
1396
1504
|
const tempOrder = this.store.order.getTempOrder();
|
|
1397
|
-
if (!((_a = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _a.length))
|
|
1505
|
+
if (!((_a = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _a.length)) {
|
|
1506
|
+
this.logPricingDiagnostics("[VenueBooking] order smart pricing recalculation skipped", {
|
|
1507
|
+
reason: "temp order has no products"
|
|
1508
|
+
});
|
|
1398
1509
|
return;
|
|
1510
|
+
}
|
|
1399
1511
|
const now = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
|
|
1400
1512
|
const catalog = this.getAllProductsForSmartPricing();
|
|
1401
1513
|
const context = this.buildSmartPricingContext();
|
|
1514
|
+
const productDiagnostics = this.isPricingDiagnosticsEnabled() ? [] : null;
|
|
1402
1515
|
for (const product of tempOrder.products) {
|
|
1403
1516
|
if ((_b = product.metadata) == null ? void 0 : _b.venue_booking) {
|
|
1404
1517
|
const mappings = this.resourceProductMap.get(product.metadata.resource_id);
|
|
1405
|
-
if (!mappings || !mappings.length)
|
|
1518
|
+
if (!mappings || !mappings.length) {
|
|
1519
|
+
productDiagnostics == null ? void 0 : productDiagnostics.push({
|
|
1520
|
+
productId: product.product_id,
|
|
1521
|
+
resourceId: product.metadata.resource_id,
|
|
1522
|
+
originalSellingPrice: product.selling_price,
|
|
1523
|
+
result: "skipped",
|
|
1524
|
+
reason: "resourceProductMap has no mapping for resource"
|
|
1525
|
+
});
|
|
1406
1526
|
continue;
|
|
1527
|
+
}
|
|
1407
1528
|
const mapping = mappings.find((m) => Number(m.productId) === Number(product.product_id)) || mappings[0];
|
|
1408
|
-
if (!mapping)
|
|
1529
|
+
if (!mapping) {
|
|
1530
|
+
productDiagnostics == null ? void 0 : productDiagnostics.push({
|
|
1531
|
+
productId: product.product_id,
|
|
1532
|
+
resourceId: product.metadata.resource_id,
|
|
1533
|
+
originalSellingPrice: product.selling_price,
|
|
1534
|
+
result: "skipped",
|
|
1535
|
+
reason: "no product mapping selected",
|
|
1536
|
+
mappings
|
|
1537
|
+
});
|
|
1409
1538
|
continue;
|
|
1539
|
+
}
|
|
1410
1540
|
const slots = (0, import_slotMerge.expandMergedSlotToIndividual)(
|
|
1411
1541
|
product,
|
|
1412
1542
|
this.store.slotConfig.slotDurationMinutes
|
|
@@ -1437,6 +1567,7 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1437
1567
|
});
|
|
1438
1568
|
const merged = (0, import_slotMerge.mergeConsecutiveSlots)(updatedSlots);
|
|
1439
1569
|
if (merged.length === 1) {
|
|
1570
|
+
const previousSellingPrice = product == null ? void 0 : product.selling_price;
|
|
1440
1571
|
this.resetProductPriceForSmartPricing({
|
|
1441
1572
|
product,
|
|
1442
1573
|
price: merged[0].totalPrice,
|
|
@@ -1445,8 +1576,37 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1445
1576
|
productId: mapping.productId
|
|
1446
1577
|
})
|
|
1447
1578
|
});
|
|
1579
|
+
productDiagnostics == null ? void 0 : productDiagnostics.push({
|
|
1580
|
+
productId: product.product_id,
|
|
1581
|
+
resourceId: product.metadata.resource_id,
|
|
1582
|
+
result: "price reset",
|
|
1583
|
+
previousSellingPrice,
|
|
1584
|
+
finalSellingPrice: product.selling_price,
|
|
1585
|
+
mapping,
|
|
1586
|
+
slots: updatedSlots,
|
|
1587
|
+
merged,
|
|
1588
|
+
slotPriceMaps: Array.from(slotPriceMaps.entries()).map(([date, priceMap]) => ({
|
|
1589
|
+
date,
|
|
1590
|
+
entries: Array.from(priceMap.entries())
|
|
1591
|
+
}))
|
|
1592
|
+
});
|
|
1593
|
+
} else {
|
|
1594
|
+
productDiagnostics == null ? void 0 : productDiagnostics.push({
|
|
1595
|
+
productId: product.product_id,
|
|
1596
|
+
resourceId: product.metadata.resource_id,
|
|
1597
|
+
originalSellingPrice: product.selling_price,
|
|
1598
|
+
result: "skipped",
|
|
1599
|
+
reason: "expanded slots did not merge into exactly one group",
|
|
1600
|
+
mapping,
|
|
1601
|
+
slots: updatedSlots,
|
|
1602
|
+
merged
|
|
1603
|
+
});
|
|
1448
1604
|
}
|
|
1449
1605
|
} else if (product.product_id != null) {
|
|
1606
|
+
const catalogProduct = productDiagnostics ? catalog == null ? void 0 : catalog.find(
|
|
1607
|
+
(item) => Number(item == null ? void 0 : item.id) === Number(product == null ? void 0 : product.product_id)
|
|
1608
|
+
) : void 0;
|
|
1609
|
+
const previousSellingPrice = product == null ? void 0 : product.selling_price;
|
|
1450
1610
|
const smartPrice = (0, import_smartPricing.getPriceForProductAtDatetime)({
|
|
1451
1611
|
products: catalog,
|
|
1452
1612
|
context,
|
|
@@ -1458,8 +1618,43 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1458
1618
|
product,
|
|
1459
1619
|
price: smartPrice
|
|
1460
1620
|
});
|
|
1621
|
+
productDiagnostics == null ? void 0 : productDiagnostics.push({
|
|
1622
|
+
productId: product.product_id,
|
|
1623
|
+
result: "price reset",
|
|
1624
|
+
previousSellingPrice,
|
|
1625
|
+
resolvedSmartPrice: smartPrice,
|
|
1626
|
+
finalSellingPrice: product.selling_price,
|
|
1627
|
+
catalogProduct: catalogProduct ? {
|
|
1628
|
+
price: catalogProduct.price,
|
|
1629
|
+
sellingPrice: catalogProduct.selling_price,
|
|
1630
|
+
dataVariants: catalogProduct.data_variants
|
|
1631
|
+
} : null
|
|
1632
|
+
});
|
|
1633
|
+
} else {
|
|
1634
|
+
productDiagnostics == null ? void 0 : productDiagnostics.push({
|
|
1635
|
+
productId: product.product_id,
|
|
1636
|
+
originalSellingPrice: product.selling_price,
|
|
1637
|
+
result: "skipped",
|
|
1638
|
+
reason: "product_id is missing"
|
|
1639
|
+
});
|
|
1461
1640
|
}
|
|
1462
1641
|
}
|
|
1642
|
+
if (productDiagnostics) {
|
|
1643
|
+
this.logPricingDiagnostics("[VenueBooking] order smart pricing recalculation detail", {
|
|
1644
|
+
now,
|
|
1645
|
+
context: {
|
|
1646
|
+
customerId: context.customerId,
|
|
1647
|
+
availableWalletIds: context.availableWalletIds,
|
|
1648
|
+
channel: context.channel,
|
|
1649
|
+
businessCode: context.businessCode,
|
|
1650
|
+
orderType: context.orderType,
|
|
1651
|
+
hasEvaluator: !!context.evaluator
|
|
1652
|
+
},
|
|
1653
|
+
catalogCount: catalog.length,
|
|
1654
|
+
resourceProductMapSize: this.resourceProductMap.size,
|
|
1655
|
+
productDiagnostics
|
|
1656
|
+
});
|
|
1657
|
+
}
|
|
1463
1658
|
}
|
|
1464
1659
|
/**
|
|
1465
1660
|
* DataVariant 重算价格后,同步刷新订单展示、Rules 与 Summary 共用的价格口径。
|
|
@@ -1804,11 +1999,6 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1804
1999
|
}
|
|
1805
2000
|
async getProductList() {
|
|
1806
2001
|
if (this.productsLoaded) {
|
|
1807
|
-
this.logPricingDiagnostics("[VenueBooking] getProductList loadAllProducts skipped", {
|
|
1808
|
-
reason: "productsLoaded is true",
|
|
1809
|
-
addonProductCount: this.getAddonProductsList().length,
|
|
1810
|
-
smartPricingProductCatalogCount: this.smartPricingProductCatalog.length
|
|
1811
|
-
});
|
|
1812
2002
|
return (0, import_utils.attachItemRuleLimitsToTopLevelProducts)(
|
|
1813
2003
|
this.getAddonProductsList(),
|
|
1814
2004
|
this.store.itemRuleQuantityLimits || []
|
|
@@ -16,7 +16,6 @@ export interface VenueBookingSmartPricingContext {
|
|
|
16
16
|
orderType?: string;
|
|
17
17
|
strategy_context?: Record<string, any>;
|
|
18
18
|
strategyConfigs?: StrategyConfig[];
|
|
19
|
-
debugLog?: (title: string, payload?: Record<string, any>) => void;
|
|
20
19
|
}
|
|
21
20
|
/** 从商品上读取展示/算价用的 price 字段 */
|
|
22
21
|
export declare function extractProductPrice(product: DataVariantProduct): string | null;
|
|
@@ -61,12 +61,10 @@ function buildDataVariantBusinessData(products, context, scheduleDateTime) {
|
|
|
61
61
|
channel: context.channel ?? strategyContext.channel,
|
|
62
62
|
orderType: context.orderType ?? strategyContext.orderType ?? strategyContext.order_type,
|
|
63
63
|
businessCode: context.businessCode ?? strategyContext.business_code ?? strategyContext.businessCode,
|
|
64
|
-
custom: strategyContext
|
|
65
|
-
debugLog: context == null ? void 0 : context.debugLog
|
|
64
|
+
custom: strategyContext
|
|
66
65
|
};
|
|
67
66
|
}
|
|
68
67
|
function formatProductsWithDataVariant(products, context, scheduleDateTime) {
|
|
69
|
-
var _a, _b, _c, _d;
|
|
70
68
|
const evaluator = context.evaluator;
|
|
71
69
|
if (!evaluator || typeof evaluator.resolveProducts !== "function") {
|
|
72
70
|
console.warn("[VenueBooking][smartPricing] dataVariantEvaluator 未注入,跳过智能定价格式化");
|
|
@@ -74,30 +72,7 @@ function formatProductsWithDataVariant(products, context, scheduleDateTime) {
|
|
|
74
72
|
}
|
|
75
73
|
const resolvedAt = scheduleDateTime || (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
|
|
76
74
|
const businessData = buildDataVariantBusinessData(products, context, resolvedAt);
|
|
77
|
-
(_a = context.debugLog) == null ? void 0 : _a.call(context, "[VenueBooking][smartPricing] formatProducts input", {
|
|
78
|
-
scheduleDateTime: resolvedAt,
|
|
79
|
-
customerId: businessData.customerId,
|
|
80
|
-
availableWalletIds: businessData.availableWalletIds,
|
|
81
|
-
channel: businessData.channel,
|
|
82
|
-
businessCode: businessData.businessCode,
|
|
83
|
-
orderType: businessData.orderType,
|
|
84
|
-
productCount: products.length,
|
|
85
|
-
products: products.map((product) => ({
|
|
86
|
-
productId: (product == null ? void 0 : product.id) ?? (product == null ? void 0 : product.product_id),
|
|
87
|
-
price: product == null ? void 0 : product.price,
|
|
88
|
-
sellingPrice: product == null ? void 0 : product.selling_price,
|
|
89
|
-
dataVariants: Array.isArray(product == null ? void 0 : product.data_variants) ? product.data_variants.map((variant) => ({
|
|
90
|
-
dataVariantRuleId: variant == null ? void 0 : variant.data_variant_rule_id,
|
|
91
|
-
data: variant == null ? void 0 : variant.data
|
|
92
|
-
})) : []
|
|
93
|
-
}))
|
|
94
|
-
});
|
|
95
75
|
const result = evaluator.resolveProducts(businessData);
|
|
96
|
-
(_d = context.debugLog) == null ? void 0 : _d.call(context, "[VenueBooking][smartPricing] formatProducts output", {
|
|
97
|
-
scheduleDateTime: resolvedAt,
|
|
98
|
-
effectiveRuleIds: Array.from(((_c = (_b = result == null ? void 0 : result.globalEffectiveRuleMap) == null ? void 0 : _b.keys) == null ? void 0 : _c.call(_b)) || []),
|
|
99
|
-
resultProducts: (result == null ? void 0 : result.products) || []
|
|
100
|
-
});
|
|
101
76
|
return Array.isArray(result == null ? void 0 : result.products) ? result.products : products;
|
|
102
77
|
}
|
|
103
78
|
function buildEvaluationDatetimes(params) {
|
|
@@ -140,7 +115,6 @@ function buildSlotStartDatetime(date, label, config) {
|
|
|
140
115
|
return (0, import_dayjs.default)(`${slotDate} ${label}`).format("YYYY-MM-DD HH:mm");
|
|
141
116
|
}
|
|
142
117
|
function buildSlotPriceMapByScheduleSegments(params) {
|
|
143
|
-
var _a, _b, _c;
|
|
144
118
|
const { products, productIds, date, timeLabels, config, context } = params;
|
|
145
119
|
const map = /* @__PURE__ */ new Map();
|
|
146
120
|
if (!productIds.length || !timeLabels.length)
|
|
@@ -153,13 +127,6 @@ function buildSlotPriceMapByScheduleSegments(params) {
|
|
|
153
127
|
const scheduleTimePoints = typeof evaluator.buildScheduleTimePoints === "function" ? evaluator.buildScheduleTimePoints(strategyConfigs, context.scheduleList || []) : [];
|
|
154
128
|
const evalDatetimes = buildEvaluationDatetimes({ date, config, scheduleTimePoints });
|
|
155
129
|
const priceCache = /* @__PURE__ */ new Map();
|
|
156
|
-
(_a = context.debugLog) == null ? void 0 : _a.call(context, "[VenueBooking][smartPricing] slot price evaluation started", {
|
|
157
|
-
date,
|
|
158
|
-
productIds,
|
|
159
|
-
scheduleTimePoints,
|
|
160
|
-
evalDatetimes,
|
|
161
|
-
timeLabels
|
|
162
|
-
});
|
|
163
130
|
for (const evalDt of evalDatetimes) {
|
|
164
131
|
const resolved = formatProductsWithDataVariant(products, context, evalDt);
|
|
165
132
|
const priceByProductId = /* @__PURE__ */ new Map();
|
|
@@ -170,14 +137,6 @@ function buildSlotPriceMapByScheduleSegments(params) {
|
|
|
170
137
|
priceByProductId.set(productId, extractProductPrice(product));
|
|
171
138
|
}
|
|
172
139
|
priceCache.set(evalDt, priceByProductId);
|
|
173
|
-
(_b = context.debugLog) == null ? void 0 : _b.call(context, "[VenueBooking][smartPricing] slot segment prices resolved", {
|
|
174
|
-
date,
|
|
175
|
-
evalDatetime: evalDt,
|
|
176
|
-
prices: productIds.map((productId) => ({
|
|
177
|
-
productId,
|
|
178
|
-
price: priceByProductId.get(productId) ?? null
|
|
179
|
-
}))
|
|
180
|
-
});
|
|
181
140
|
}
|
|
182
141
|
for (const label of timeLabels) {
|
|
183
142
|
const slotStart = buildSlotStartDatetime(date, label, config);
|
|
@@ -191,10 +150,6 @@ function buildSlotPriceMapByScheduleSegments(params) {
|
|
|
191
150
|
}
|
|
192
151
|
}
|
|
193
152
|
}
|
|
194
|
-
(_c = context.debugLog) == null ? void 0 : _c.call(context, "[VenueBooking][smartPricing] slot price map completed", {
|
|
195
|
-
date,
|
|
196
|
-
entries: Array.from(map.entries()).map(([key, price]) => ({ key, price }))
|
|
197
|
-
});
|
|
198
153
|
return map;
|
|
199
154
|
}
|
|
200
155
|
function getPriceForProductAtDatetime(params) {
|