@pisell/pisellos 0.10.6 → 0.10.7
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/modules/Order/index.d.ts +2 -1
- package/dist/modules/Order/index.js +85 -58
- package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +15 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.js +75 -0
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +13 -1
- package/dist/solution/BookingTicket/index.js +18 -18
- package/dist/solution/UnifiedBookingSales/index.d.ts +11 -0
- package/dist/solution/UnifiedBookingSales/index.js +62 -9
- package/lib/model/strategy/adapter/promotion/index.js +0 -51
- package/lib/modules/Order/index.d.ts +2 -1
- package/lib/modules/Order/index.js +45 -10
- package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +15 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.js +70 -0
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +13 -1
- package/lib/solution/BookingTicket/index.js +5 -5
- package/lib/solution/UnifiedBookingSales/index.d.ts +11 -0
- package/lib/solution/UnifiedBookingSales/index.js +45 -0
- package/package.json +1 -1
|
@@ -237,6 +237,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
237
237
|
private sanitizeOrderProductForTempOrder;
|
|
238
238
|
private sanitizeTempOrderProducts;
|
|
239
239
|
private ensureExtend;
|
|
240
|
+
private repairDuplicateProductLineIdentities;
|
|
240
241
|
private captureProductRuntime;
|
|
241
242
|
private createLinkedProductAndBooking;
|
|
242
243
|
/**
|
|
@@ -497,7 +498,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
497
498
|
generateIdempotencyToken(): string;
|
|
498
499
|
syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
|
|
499
500
|
createOrder(params: CommitOrderParams['query']): {
|
|
500
|
-
type: "
|
|
501
|
+
type: "appointment_booking" | "virtual";
|
|
501
502
|
platform: string;
|
|
502
503
|
sales_channel: string;
|
|
503
504
|
order_sales_channel: string;
|
|
@@ -41,7 +41,7 @@ import { processCartPromotion, appendPromotionTags as _appendPromotionTags, getO
|
|
|
41
41
|
import { buildProductLineFingerprint, getProductIdentityIndex, getSafeProductNum, isIdentityMatch, normalizeOrderProduct } from "../../solution/ScanOrder/utils";
|
|
42
42
|
import { syncManualProductDiscountProductNum } from "./utils/manualProductDiscount";
|
|
43
43
|
import { expandHydratedProductsForDiscountCollection, restoreHydratedBundleDiscounts } from "./utils/bundleDiscountHydration";
|
|
44
|
-
import { getOrderCollectionPersistentId, getOrderCollectionUid, normalizeOrderCollections, setOrderCollectionUid } from "./utils/orderCollectionIdentity";
|
|
44
|
+
import { getOrderCollectionPersistentId, getOrderCollectionUid, normalizeOrderCollections, repairDuplicateProductLineIdentities as repairDuplicateOrderProductLineIdentities, setOrderCollectionUid } from "./utils/orderCollectionIdentity";
|
|
45
45
|
import { DiscountModule } from "../Discount";
|
|
46
46
|
import { RulesModule } from "../Rules";
|
|
47
47
|
import { UnavailableReason } from "../Rules/types";
|
|
@@ -890,6 +890,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
890
890
|
discount_list: normalizeOrderProductDiscountList(syncManualProductDiscountProductNum(mergedProduct.discount_list, mergedProduct.num))
|
|
891
891
|
});
|
|
892
892
|
}));
|
|
893
|
+
this.repairDuplicateProductLineIdentities(tempOrder);
|
|
893
894
|
}
|
|
894
895
|
if (result !== null && result !== void 0 && result.discountList) {
|
|
895
896
|
var _this$store$discount15;
|
|
@@ -2608,6 +2609,21 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
2608
2609
|
}
|
|
2609
2610
|
return tempOrder._extend;
|
|
2610
2611
|
}
|
|
2612
|
+
}, {
|
|
2613
|
+
key: "repairDuplicateProductLineIdentities",
|
|
2614
|
+
value: function repairDuplicateProductLineIdentities(tempOrder) {
|
|
2615
|
+
var _tempOrder$_extend7;
|
|
2616
|
+
var result = repairDuplicateOrderProductLineIdentities(tempOrder.products, (_tempOrder$_extend7 = tempOrder._extend) === null || _tempOrder$_extend7 === void 0 ? void 0 : _tempOrder$_extend7.productsByUid);
|
|
2617
|
+
if (!result.repairs.length) return;
|
|
2618
|
+
tempOrder.products = result.products;
|
|
2619
|
+
if (result.productsByUid) {
|
|
2620
|
+
this.ensureExtend(tempOrder).productsByUid = result.productsByUid;
|
|
2621
|
+
}
|
|
2622
|
+
this.logWarning('Repaired duplicate product line identities', {
|
|
2623
|
+
repairCount: result.repairs.length,
|
|
2624
|
+
repairs: result.repairs
|
|
2625
|
+
});
|
|
2626
|
+
}
|
|
2611
2627
|
}, {
|
|
2612
2628
|
key: "captureProductRuntime",
|
|
2613
2629
|
value: function captureProductRuntime(tempOrder, rawProduct, normalizedProduct, existedUid) {
|
|
@@ -2880,9 +2896,9 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
2880
2896
|
}, {
|
|
2881
2897
|
key: "applyOrderProductsDepositSummary",
|
|
2882
2898
|
value: function applyOrderProductsDepositSummary(tempOrder, summary) {
|
|
2883
|
-
var _tempOrder$
|
|
2899
|
+
var _tempOrder$_extend8;
|
|
2884
2900
|
var depositSummary = calculateOrderProductsDeposit(tempOrder.products || [], {
|
|
2885
|
-
productsByUid: (_tempOrder$
|
|
2901
|
+
productsByUid: (_tempOrder$_extend8 = tempOrder._extend) === null || _tempOrder$_extend8 === void 0 ? void 0 : _tempOrder$_extend8.productsByUid
|
|
2886
2902
|
});
|
|
2887
2903
|
var manualDepositOverride = this.getManualDepositOverride(tempOrder);
|
|
2888
2904
|
var currentStructuralFingerprint = manualDepositOverride ? this.buildOrderProductsStructuralFingerprint(tempOrder.products) : '';
|
|
@@ -4557,6 +4573,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
4557
4573
|
case 0:
|
|
4558
4574
|
product_id = params.product_id, product_variant_id = params.product_variant_id, num = params.num, unique_identification_number = params.unique_identification_number, identity_key = params.identity_key, product_sku = params.product_sku, product_bundle = params.product_bundle;
|
|
4559
4575
|
tempOrder = this.ensureTempOrder();
|
|
4576
|
+
this.repairDuplicateProductLineIdentities(tempOrder);
|
|
4560
4577
|
identityLookup = {
|
|
4561
4578
|
product_id: product_id,
|
|
4562
4579
|
product_variant_id: product_variant_id
|
|
@@ -4582,11 +4599,11 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
4582
4599
|
productIndex = getProductIdentityIndex(tempOrder.products, identityLookup);
|
|
4583
4600
|
}
|
|
4584
4601
|
if (!(productIndex === -1)) {
|
|
4585
|
-
_context27.next =
|
|
4602
|
+
_context27.next = 13;
|
|
4586
4603
|
break;
|
|
4587
4604
|
}
|
|
4588
4605
|
throw new Error('[Order] 目标商品不存在,无法更新数量');
|
|
4589
|
-
case
|
|
4606
|
+
case 13:
|
|
4590
4607
|
targetProduct = tempOrder.products[productIndex];
|
|
4591
4608
|
normalizedProduct = normalizeOrderProduct(_objectSpread(_objectSpread({}, targetProduct), {}, {
|
|
4592
4609
|
num: getSafeProductNum(num),
|
|
@@ -4596,22 +4613,22 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
4596
4613
|
}));
|
|
4597
4614
|
normalizedProduct.discount_list = normalizeOrderProductDiscountList(normalizedProduct.discount_list);
|
|
4598
4615
|
tempOrder.products[productIndex] = normalizedProduct;
|
|
4599
|
-
_context27.next =
|
|
4616
|
+
_context27.next = 19;
|
|
4600
4617
|
return this.applyPromotion();
|
|
4601
|
-
case
|
|
4618
|
+
case 19:
|
|
4602
4619
|
this.applyDiscount();
|
|
4603
4620
|
this.sanitizeTempOrderProducts(tempOrder);
|
|
4604
|
-
_context27.next =
|
|
4621
|
+
_context27.next = 23;
|
|
4605
4622
|
return this.recalculateSummary({
|
|
4606
4623
|
createIfMissing: true
|
|
4607
4624
|
});
|
|
4608
|
-
case
|
|
4625
|
+
case 23:
|
|
4609
4626
|
this.persistTempOrder();
|
|
4610
4627
|
this.logInfo('updateOrderProductQuantity success', {
|
|
4611
4628
|
params: params
|
|
4612
4629
|
});
|
|
4613
4630
|
return _context27.abrupt("return", tempOrder.products);
|
|
4614
|
-
case
|
|
4631
|
+
case 26:
|
|
4615
4632
|
case "end":
|
|
4616
4633
|
return _context27.stop();
|
|
4617
4634
|
}
|
|
@@ -4704,12 +4721,13 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
4704
4721
|
while (1) switch (_context30.prev = _context30.next) {
|
|
4705
4722
|
case 0:
|
|
4706
4723
|
tempOrder = this.ensureTempOrder();
|
|
4724
|
+
this.repairDuplicateProductLineIdentities(tempOrder);
|
|
4707
4725
|
if (identities.length) {
|
|
4708
|
-
_context30.next =
|
|
4726
|
+
_context30.next = 4;
|
|
4709
4727
|
break;
|
|
4710
4728
|
}
|
|
4711
4729
|
return _context30.abrupt("return", tempOrder.products);
|
|
4712
|
-
case
|
|
4730
|
+
case 4:
|
|
4713
4731
|
productsBeforeRemove = tempOrder.products || [];
|
|
4714
4732
|
bookingsBeforeRemove = tempOrder.bookings || [];
|
|
4715
4733
|
matchedProducts = productsBeforeRemove.filter(function (item) {
|
|
@@ -4731,7 +4749,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
4731
4749
|
}
|
|
4732
4750
|
linkedBookingUidsToRemove = new Set();
|
|
4733
4751
|
_iterator21 = _createForOfIteratorHelper(matchedProducts);
|
|
4734
|
-
_context30.prev =
|
|
4752
|
+
_context30.prev = 12;
|
|
4735
4753
|
_loop3 = /*#__PURE__*/_regeneratorRuntime().mark(function _loop3() {
|
|
4736
4754
|
var _metadata11, _metadata12, _metadata13, _metadata14;
|
|
4737
4755
|
var product, productUid, productBookingUid, isAddTimeProduct;
|
|
@@ -4766,33 +4784,33 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
4766
4784
|
}, _loop3);
|
|
4767
4785
|
});
|
|
4768
4786
|
_iterator21.s();
|
|
4769
|
-
case
|
|
4787
|
+
case 15:
|
|
4770
4788
|
if ((_step21 = _iterator21.n()).done) {
|
|
4771
|
-
_context30.next =
|
|
4789
|
+
_context30.next = 21;
|
|
4772
4790
|
break;
|
|
4773
4791
|
}
|
|
4774
|
-
return _context30.delegateYield(_loop3(), "t0",
|
|
4775
|
-
case
|
|
4792
|
+
return _context30.delegateYield(_loop3(), "t0", 17);
|
|
4793
|
+
case 17:
|
|
4776
4794
|
if (!_context30.t0) {
|
|
4777
|
-
_context30.next =
|
|
4795
|
+
_context30.next = 19;
|
|
4778
4796
|
break;
|
|
4779
4797
|
}
|
|
4780
|
-
return _context30.abrupt("continue",
|
|
4781
|
-
case
|
|
4782
|
-
_context30.next =
|
|
4798
|
+
return _context30.abrupt("continue", 19);
|
|
4799
|
+
case 19:
|
|
4800
|
+
_context30.next = 15;
|
|
4783
4801
|
break;
|
|
4784
|
-
case
|
|
4785
|
-
_context30.next =
|
|
4802
|
+
case 21:
|
|
4803
|
+
_context30.next = 26;
|
|
4786
4804
|
break;
|
|
4787
|
-
case
|
|
4788
|
-
_context30.prev =
|
|
4789
|
-
_context30.t1 = _context30["catch"](
|
|
4805
|
+
case 23:
|
|
4806
|
+
_context30.prev = 23;
|
|
4807
|
+
_context30.t1 = _context30["catch"](12);
|
|
4790
4808
|
_iterator21.e(_context30.t1);
|
|
4791
|
-
case
|
|
4792
|
-
_context30.prev =
|
|
4809
|
+
case 26:
|
|
4810
|
+
_context30.prev = 26;
|
|
4793
4811
|
_iterator21.f();
|
|
4794
|
-
return _context30.finish(
|
|
4795
|
-
case
|
|
4812
|
+
return _context30.finish(26);
|
|
4813
|
+
case 29:
|
|
4796
4814
|
if (linkedBookingUidsToRemove.size > 0) {
|
|
4797
4815
|
// 删除主预约商品时,同步移除挂在同一 booking_uid 下的加时商品,避免残留孤儿行。
|
|
4798
4816
|
tempOrder.products = (tempOrder.products || []).filter(function (line) {
|
|
@@ -4802,18 +4820,18 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
4802
4820
|
return !(isAddTimeProduct && lineBookingUid !== undefined && lineBookingUid !== null && linkedBookingUidsToRemove.has(String(lineBookingUid)));
|
|
4803
4821
|
});
|
|
4804
4822
|
}
|
|
4805
|
-
_context30.next =
|
|
4823
|
+
_context30.next = 32;
|
|
4806
4824
|
return this.finalizeAfterProductsMutation(tempOrder);
|
|
4807
|
-
case
|
|
4825
|
+
case 32:
|
|
4808
4826
|
this.logInfo('removeProductsFromOrder success', {
|
|
4809
4827
|
identities: identities
|
|
4810
4828
|
});
|
|
4811
4829
|
return _context30.abrupt("return", tempOrder.products);
|
|
4812
|
-
case
|
|
4830
|
+
case 34:
|
|
4813
4831
|
case "end":
|
|
4814
4832
|
return _context30.stop();
|
|
4815
4833
|
}
|
|
4816
|
-
}, _callee27, this, [[
|
|
4834
|
+
}, _callee27, this, [[12, 23, 26, 29]]);
|
|
4817
4835
|
}));
|
|
4818
4836
|
function removeProductsFromOrder(_x34) {
|
|
4819
4837
|
return _removeProductsFromOrder.apply(this, arguments);
|
|
@@ -5911,26 +5929,35 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
5911
5929
|
key: "hydrateTempOrderFromRecord",
|
|
5912
5930
|
value: (function () {
|
|
5913
5931
|
var _hydrateTempOrderFromRecord = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee44(record, options) {
|
|
5914
|
-
var _this$store$discount22;
|
|
5915
|
-
var sourceRaw, identityReadySource, normalizedCollections, raw, hasIdentityChanges, identityLogMetadata, hasIdentityWarnings, isSessionStorageHydrate, nextTempOrder, _this$store$discount20, _this$store$discount21, restoredSessionDiscounts, nextExtend, sourceLastOrderInfo, isDraftOrder, syntheticIdentityOptions, rawSummary, summarySurcharges, hadSyntheticDraftOrderId, hydratedEditDiscounts, currentDiscounts, currentScanDiscounts, hydratedDiscountIds, retainedScanDiscounts, nextDiscounts, shouldSkipEmptyDiscountSync, _this$store$discount23, _this$store$discount24;
|
|
5932
|
+
var _sourceRaw$_extend, _this$store$discount22;
|
|
5933
|
+
var sourceRaw, duplicateProductIdentityRepair, duplicateIdentityReadySource, identityReadySource, normalizedCollections, raw, hasIdentityChanges, identityLogMetadata, hasIdentityWarnings, isSessionStorageHydrate, nextTempOrder, _this$store$discount20, _this$store$discount21, restoredSessionDiscounts, nextExtend, sourceLastOrderInfo, isDraftOrder, syntheticIdentityOptions, rawSummary, summarySurcharges, hadSyntheticDraftOrderId, hydratedEditDiscounts, currentDiscounts, currentScanDiscounts, hydratedDiscountIds, retainedScanDiscounts, nextDiscounts, shouldSkipEmptyDiscountSync, _this$store$discount23, _this$store$discount24;
|
|
5916
5934
|
return _regeneratorRuntime().wrap(function _callee44$(_context47) {
|
|
5917
5935
|
while (1) switch (_context47.prev = _context47.next) {
|
|
5918
5936
|
case 0:
|
|
5919
5937
|
sourceRaw = record && _typeof(record) === 'object' && record.data && record.order_id == null ? record.data : record || {};
|
|
5920
|
-
|
|
5938
|
+
duplicateProductIdentityRepair = repairDuplicateOrderProductLineIdentities(Array.isArray(sourceRaw.products) ? sourceRaw.products : [], (_sourceRaw$_extend = sourceRaw._extend) === null || _sourceRaw$_extend === void 0 ? void 0 : _sourceRaw$_extend.productsByUid);
|
|
5939
|
+
duplicateIdentityReadySource = duplicateProductIdentityRepair.repairs.length ? _objectSpread(_objectSpread({}, sourceRaw), {}, {
|
|
5940
|
+
products: duplicateProductIdentityRepair.products
|
|
5941
|
+
}, duplicateProductIdentityRepair.productsByUid ? {
|
|
5942
|
+
_extend: _objectSpread(_objectSpread({}, sourceRaw._extend || {}), {}, {
|
|
5943
|
+
productsByUid: duplicateProductIdentityRepair.productsByUid
|
|
5944
|
+
})
|
|
5945
|
+
} : {}) : sourceRaw;
|
|
5946
|
+
identityReadySource = this.seedAnonymousBookingUidsFromProducts(duplicateIdentityReadySource);
|
|
5921
5947
|
normalizedCollections = normalizeOrderCollections(identityReadySource);
|
|
5922
5948
|
raw = normalizedCollections.order;
|
|
5923
|
-
hasIdentityChanges = Object.values(normalizedCollections.stats).some(function (stats) {
|
|
5949
|
+
hasIdentityChanges = duplicateProductIdentityRepair.repairs.length > 0 || Object.values(normalizedCollections.stats).some(function (stats) {
|
|
5924
5950
|
return stats.backfilledUidCount > 0 || stats.collapsedDuplicateCount > 0 || stats.uidConflictCount > 0 || stats.anonymousRowCount > 0;
|
|
5925
5951
|
});
|
|
5926
5952
|
if (hasIdentityChanges) {
|
|
5927
5953
|
identityLogMetadata = {
|
|
5928
5954
|
collections: normalizedCollections.stats,
|
|
5929
|
-
uidRemapCount: normalizedCollections.uidRemaps.length
|
|
5955
|
+
uidRemapCount: normalizedCollections.uidRemaps.length,
|
|
5956
|
+
duplicateProductUidRepairCount: duplicateProductIdentityRepair.repairs.length
|
|
5930
5957
|
};
|
|
5931
5958
|
hasIdentityWarnings = Object.values(normalizedCollections.stats).some(function (stats) {
|
|
5932
5959
|
return stats.uidConflictCount > 0 || stats.anonymousRowCount > 0;
|
|
5933
|
-
});
|
|
5960
|
+
}) || duplicateProductIdentityRepair.repairs.length > 0;
|
|
5934
5961
|
if (hasIdentityWarnings) {
|
|
5935
5962
|
this.logWarning('Normalized hydrated order collection identities', identityLogMetadata);
|
|
5936
5963
|
} else {
|
|
@@ -5943,7 +5970,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
5943
5970
|
});
|
|
5944
5971
|
this.store.tempOrder = nextTempOrder;
|
|
5945
5972
|
if (!isSessionStorageHydrate) {
|
|
5946
|
-
_context47.next =
|
|
5973
|
+
_context47.next = 29;
|
|
5947
5974
|
break;
|
|
5948
5975
|
}
|
|
5949
5976
|
// 会话快照是未提交购物车,不应获得编辑订单的 saved/edit 标记与服务端基线。
|
|
@@ -5959,24 +5986,24 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
5959
5986
|
nextTempOrder.discount_list = restoredSessionDiscounts;
|
|
5960
5987
|
this.store.summary = createEmptySummary();
|
|
5961
5988
|
this.store.lastOrderInfo = undefined;
|
|
5962
|
-
_context47.next = 20;
|
|
5963
|
-
return (_this$store$discount20 = this.store.discount) === null || _this$store$discount20 === void 0 ? void 0 : _this$store$discount20.setOriginalDiscountList(cloneDeep(restoredSessionDiscounts));
|
|
5964
|
-
case 20:
|
|
5965
5989
|
_context47.next = 22;
|
|
5966
|
-
return (_this$store$
|
|
5990
|
+
return (_this$store$discount20 = this.store.discount) === null || _this$store$discount20 === void 0 ? void 0 : _this$store$discount20.setOriginalDiscountList(cloneDeep(restoredSessionDiscounts));
|
|
5967
5991
|
case 22:
|
|
5992
|
+
_context47.next = 24;
|
|
5993
|
+
return (_this$store$discount21 = this.store.discount) === null || _this$store$discount21 === void 0 ? void 0 : _this$store$discount21.setDiscountList(cloneDeep(restoredSessionDiscounts));
|
|
5994
|
+
case 24:
|
|
5968
5995
|
if (!(options !== null && options !== void 0 && options.recalcOnHydrate)) {
|
|
5969
|
-
_context47.next =
|
|
5996
|
+
_context47.next = 27;
|
|
5970
5997
|
break;
|
|
5971
5998
|
}
|
|
5972
|
-
_context47.next =
|
|
5999
|
+
_context47.next = 27;
|
|
5973
6000
|
return this.recalculateSummary({
|
|
5974
6001
|
createIfMissing: false
|
|
5975
6002
|
});
|
|
5976
|
-
case
|
|
6003
|
+
case 27:
|
|
5977
6004
|
this.persistTempOrder();
|
|
5978
6005
|
return _context47.abrupt("return", nextTempOrder);
|
|
5979
|
-
case
|
|
6006
|
+
case 29:
|
|
5980
6007
|
// Server list compatibility may synthesize order_id from external_sale_number; tempOrder must not.
|
|
5981
6008
|
sourceLastOrderInfo = sourceRaw.lastOrderInfo || sourceRaw;
|
|
5982
6009
|
isDraftOrder = Number(nextTempOrder.is_draft_order || 0) === 1;
|
|
@@ -6021,28 +6048,28 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
6021
6048
|
nextDiscounts = [].concat(_toConsumableArray(hydratedEditDiscounts), _toConsumableArray(retainedScanDiscounts));
|
|
6022
6049
|
shouldSkipEmptyDiscountSync = nextDiscounts.length === 0 && currentDiscounts.length === 0;
|
|
6023
6050
|
if (shouldSkipEmptyDiscountSync) {
|
|
6024
|
-
_context47.next =
|
|
6051
|
+
_context47.next = 52;
|
|
6025
6052
|
break;
|
|
6026
6053
|
}
|
|
6027
6054
|
OrderModule.populateSavedAmounts(nextTempOrder.products, nextDiscounts);
|
|
6028
|
-
_context47.next = 48;
|
|
6029
|
-
return (_this$store$discount23 = this.store.discount) === null || _this$store$discount23 === void 0 ? void 0 : _this$store$discount23.setOriginalDiscountList(nextDiscounts);
|
|
6030
|
-
case 48:
|
|
6031
6055
|
_context47.next = 50;
|
|
6032
|
-
return (_this$store$
|
|
6056
|
+
return (_this$store$discount23 = this.store.discount) === null || _this$store$discount23 === void 0 ? void 0 : _this$store$discount23.setOriginalDiscountList(nextDiscounts);
|
|
6033
6057
|
case 50:
|
|
6058
|
+
_context47.next = 52;
|
|
6059
|
+
return (_this$store$discount24 = this.store.discount) === null || _this$store$discount24 === void 0 ? void 0 : _this$store$discount24.setDiscountList(nextDiscounts);
|
|
6060
|
+
case 52:
|
|
6034
6061
|
if (!(options !== null && options !== void 0 && options.recalcOnHydrate)) {
|
|
6035
|
-
_context47.next =
|
|
6062
|
+
_context47.next = 55;
|
|
6036
6063
|
break;
|
|
6037
6064
|
}
|
|
6038
|
-
_context47.next =
|
|
6065
|
+
_context47.next = 55;
|
|
6039
6066
|
return this.recalculateSummary({
|
|
6040
6067
|
createIfMissing: false
|
|
6041
6068
|
});
|
|
6042
|
-
case
|
|
6069
|
+
case 55:
|
|
6043
6070
|
this.persistTempOrder();
|
|
6044
6071
|
return _context47.abrupt("return", nextTempOrder);
|
|
6045
|
-
case
|
|
6072
|
+
case 57:
|
|
6046
6073
|
case "end":
|
|
6047
6074
|
return _context47.stop();
|
|
6048
6075
|
}
|
|
@@ -24,6 +24,16 @@ export interface NormalizeOrderCollectionsResult<T> {
|
|
|
24
24
|
stats: Record<OrderCollectionKind, OrderCollectionIdentityStats>;
|
|
25
25
|
uidRemaps: OrderCollectionUidRemap[];
|
|
26
26
|
}
|
|
27
|
+
export interface ProductLineIdentityRepair {
|
|
28
|
+
index: number;
|
|
29
|
+
from: string;
|
|
30
|
+
to: string;
|
|
31
|
+
}
|
|
32
|
+
export interface RepairDuplicateProductLineIdentitiesResult<T> {
|
|
33
|
+
products: T[];
|
|
34
|
+
productsByUid?: Record<string, Record<string, any>>;
|
|
35
|
+
repairs: ProductLineIdentityRepair[];
|
|
36
|
+
}
|
|
27
37
|
export declare function createUuidV4(): string;
|
|
28
38
|
export declare function isBlankOrderCollectionIdentity(value: unknown): boolean;
|
|
29
39
|
export declare function getOrderCollectionPersistentId(kind: OrderCollectionKind, item: unknown): string | null;
|
|
@@ -31,6 +41,11 @@ export declare function getOrderCollectionUid(kind: OrderCollectionKind, item: u
|
|
|
31
41
|
export declare function buildOrderCollectionFallbackUid(kind: OrderCollectionKind, persistentId: string | number): string;
|
|
32
42
|
export declare function getOrderCollectionReferenceUid(kind: OrderCollectionKind, item: unknown): string | null;
|
|
33
43
|
export declare function setOrderCollectionUid<T>(kind: OrderCollectionKind, item: T, uid: string): T;
|
|
44
|
+
/**
|
|
45
|
+
* Rules 会把同一商品按商品券拆成多条真实订单行。拆行结果会继承原商品 UID,
|
|
46
|
+
* 因此必须在通用 collection normalization 之前为后续行派生稳定身份,避免被折叠。
|
|
47
|
+
*/
|
|
48
|
+
export declare function repairDuplicateProductLineIdentities<T extends Record<string, any>>(products: T[] | null | undefined, productsByUid?: Record<string, Record<string, any>> | null): RepairDuplicateProductLineIdentitiesResult<T>;
|
|
34
49
|
/**
|
|
35
50
|
* 持久化行 ID 是服务端事实主键;只有至少一侧尚未持久化时,才允许用 runtime UID 对齐。
|
|
36
51
|
*/
|
|
@@ -74,6 +74,81 @@ export function setOrderCollectionUid(kind, item, uid) {
|
|
|
74
74
|
delete record[uidField];
|
|
75
75
|
return record;
|
|
76
76
|
}
|
|
77
|
+
function getGoodPassResourceId(product) {
|
|
78
|
+
var _ref, _ref2, _goodPass$discount$re, _goodPass$discount;
|
|
79
|
+
var goodPass = (product.discount_list || []).find(function (item) {
|
|
80
|
+
var _item$discount, _item$discount2;
|
|
81
|
+
var type = (item === null || item === void 0 ? void 0 : item.type) || (item === null || item === void 0 ? void 0 : item.tag) || (item === null || item === void 0 || (_item$discount = item.discount) === null || _item$discount === void 0 ? void 0 : _item$discount.type) || (item === null || item === void 0 || (_item$discount2 = item.discount) === null || _item$discount2 === void 0 ? void 0 : _item$discount2.tag);
|
|
82
|
+
return type === 'good_pass';
|
|
83
|
+
});
|
|
84
|
+
if (!goodPass) return null;
|
|
85
|
+
var resourceId = (_ref = (_ref2 = (_goodPass$discount$re = (_goodPass$discount = goodPass.discount) === null || _goodPass$discount === void 0 ? void 0 : _goodPass$discount.resource_id) !== null && _goodPass$discount$re !== void 0 ? _goodPass$discount$re : goodPass.resource_id) !== null && _ref2 !== void 0 ? _ref2 : goodPass.discount_id) !== null && _ref !== void 0 ? _ref : goodPass.id;
|
|
86
|
+
return isBlankOrderCollectionIdentity(resourceId) ? null : String(resourceId);
|
|
87
|
+
}
|
|
88
|
+
function buildSplitProductUid(originalUid, product, duplicateOrdinal) {
|
|
89
|
+
var encodedOriginalUid = encodeURIComponent(originalUid);
|
|
90
|
+
var resourceId = getGoodPassResourceId(product);
|
|
91
|
+
if (resourceId) {
|
|
92
|
+
return "os-split:product:".concat(encodedOriginalUid, ":good-pass:").concat(encodeURIComponent(resourceId), ":").concat(duplicateOrdinal);
|
|
93
|
+
}
|
|
94
|
+
return "os-split:product:".concat(encodedOriginalUid, ":duplicate:").concat(duplicateOrdinal);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Rules 会把同一商品按商品券拆成多条真实订单行。拆行结果会继承原商品 UID,
|
|
99
|
+
* 因此必须在通用 collection normalization 之前为后续行派生稳定身份,避免被折叠。
|
|
100
|
+
*/
|
|
101
|
+
export function repairDuplicateProductLineIdentities(products, productsByUid) {
|
|
102
|
+
var repairedProducts = cloneDeep(products || []);
|
|
103
|
+
var repairedProductsByUid = productsByUid ? cloneDeep(productsByUid) : undefined;
|
|
104
|
+
var occupiedUids = new Set(repairedProducts.map(function (product) {
|
|
105
|
+
return getOrderCollectionUid('product', product);
|
|
106
|
+
}).filter(function (uid) {
|
|
107
|
+
return Boolean(uid);
|
|
108
|
+
}));
|
|
109
|
+
Object.keys(repairedProductsByUid || {}).forEach(function (uid) {
|
|
110
|
+
return occupiedUids.add(uid);
|
|
111
|
+
});
|
|
112
|
+
var occurrences = new Map();
|
|
113
|
+
var repairs = [];
|
|
114
|
+
repairedProducts.forEach(function (product, index) {
|
|
115
|
+
var originalUid = getOrderCollectionUid('product', product);
|
|
116
|
+
if (!originalUid) return;
|
|
117
|
+
var occurrence = (occurrences.get(originalUid) || 0) + 1;
|
|
118
|
+
occurrences.set(originalUid, occurrence);
|
|
119
|
+
if (occurrence === 1) return;
|
|
120
|
+
var duplicateOrdinal = occurrence - 1;
|
|
121
|
+
var baseCandidate = buildSplitProductUid(originalUid, product, duplicateOrdinal);
|
|
122
|
+
var nextUid = baseCandidate;
|
|
123
|
+
var conflictOrdinal = 1;
|
|
124
|
+
while (occupiedUids.has(nextUid)) {
|
|
125
|
+
nextUid = "".concat(baseCandidate, ":conflict:").concat(conflictOrdinal);
|
|
126
|
+
conflictOrdinal += 1;
|
|
127
|
+
}
|
|
128
|
+
var repairedProduct = setOrderCollectionUid('product', product, nextUid);
|
|
129
|
+
repairedProduct.identity_key = nextUid;
|
|
130
|
+
repairedProducts[index] = repairedProduct;
|
|
131
|
+
occupiedUids.add(nextUid);
|
|
132
|
+
repairs.push({
|
|
133
|
+
index: index,
|
|
134
|
+
from: originalUid,
|
|
135
|
+
to: nextUid
|
|
136
|
+
});
|
|
137
|
+
var runtimeSource = repairedProductsByUid === null || repairedProductsByUid === void 0 ? void 0 : repairedProductsByUid[originalUid];
|
|
138
|
+
if (runtimeSource && repairedProductsByUid) {
|
|
139
|
+
repairedProductsByUid[nextUid] = _objectSpread(_objectSpread({}, cloneDeep(runtimeSource)), runtimeSource.rowKey !== undefined ? {
|
|
140
|
+
rowKey: nextUid
|
|
141
|
+
} : {});
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
return _objectSpread(_objectSpread({
|
|
145
|
+
products: repairedProducts
|
|
146
|
+
}, repairedProductsByUid ? {
|
|
147
|
+
productsByUid: repairedProductsByUid
|
|
148
|
+
} : {}), {}, {
|
|
149
|
+
repairs: repairs
|
|
150
|
+
});
|
|
151
|
+
}
|
|
77
152
|
|
|
78
153
|
/**
|
|
79
154
|
* 持久化行 ID 是服务端事实主键;只有至少一侧尚未持久化时,才允许用 runtime UID 对齐。
|
|
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
326
326
|
date: string;
|
|
327
327
|
status: string;
|
|
328
328
|
week: string;
|
|
329
|
-
weekNum: 0 |
|
|
329
|
+
weekNum: 0 | 5 | 2 | 1 | 6 | 4 | 3;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -447,7 +447,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
447
447
|
* 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
|
|
448
448
|
* 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
|
|
449
449
|
*/
|
|
450
|
-
decideAddProduct(item: any, options?: Partial<AddProductDecideContext>):
|
|
450
|
+
decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
|
|
451
|
+
action: "reloadCatalog";
|
|
452
|
+
} | {
|
|
453
|
+
action: "add";
|
|
454
|
+
cacheItem: any;
|
|
455
|
+
} | {
|
|
456
|
+
action: "requiresDetail";
|
|
457
|
+
payload: AddProductRequiresDetailPayload;
|
|
458
|
+
} | {
|
|
459
|
+
action: "requiresBookingEdit";
|
|
460
|
+
cacheItem: any;
|
|
461
|
+
payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
|
|
462
|
+
};
|
|
451
463
|
/** 规格弹窗 callback 后的第二段决策。 */
|
|
452
464
|
decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
|
|
453
465
|
/**
|
|
@@ -402,35 +402,35 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
|
|
|
402
402
|
value: function () {
|
|
403
403
|
var _configureIdGeneratorFromOpenData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
|
|
404
404
|
var _openDataConfig, _openDataConfig2, _openDataConfig3, _openDataConfig4, _openDataConfig5, _openDataConfig6;
|
|
405
|
-
var
|
|
405
|
+
var idGenerator, openDataConfig, receiptSequenceLength, receiptSequenceStart, prefix, shopOrderPrefix, resetReceiptSequenceDaily, operatingDayBoundary, deviceId, businessCode;
|
|
406
406
|
return _regeneratorRuntime().wrap(function _callee5$(_context5) {
|
|
407
407
|
while (1) switch (_context5.prev = _context5.next) {
|
|
408
408
|
case 0:
|
|
409
409
|
// 业务码切换或配置失败时不能复用上一次初始化的短号。
|
|
410
410
|
this.setPaymentNumberDevicePrefix(null);
|
|
411
|
-
openDataConfig = null;
|
|
412
|
-
_context5.prev = 2;
|
|
413
|
-
_context5.next = 5;
|
|
414
|
-
return this.loadOpenDataConfig();
|
|
415
|
-
case 5:
|
|
416
|
-
openDataConfig = _context5.sent;
|
|
417
|
-
_context5.next = 12;
|
|
418
|
-
break;
|
|
419
|
-
case 8:
|
|
420
|
-
_context5.prev = 8;
|
|
421
|
-
_context5.t0 = _context5["catch"](2);
|
|
422
|
-
console.warn('[BookingTicket] OpenData 配置加载失败,跳过 idGenerator 配置', _context5.t0);
|
|
423
|
-
return _context5.abrupt("return");
|
|
424
|
-
case 12:
|
|
425
|
-
// if (!openDataConfig) return;
|
|
426
411
|
idGenerator = this.getIdGeneratorPlugin();
|
|
427
412
|
if (idGenerator !== null && idGenerator !== void 0 && idGenerator.configure) {
|
|
428
|
-
_context5.next =
|
|
413
|
+
_context5.next = 5;
|
|
429
414
|
break;
|
|
430
415
|
}
|
|
431
416
|
console.warn('[BookingTicket] idGenerator 插件不可用,跳过配置');
|
|
432
417
|
return _context5.abrupt("return");
|
|
418
|
+
case 5:
|
|
419
|
+
openDataConfig = null;
|
|
420
|
+
_context5.prev = 6;
|
|
421
|
+
_context5.next = 9;
|
|
422
|
+
return this.loadOpenDataConfig();
|
|
423
|
+
case 9:
|
|
424
|
+
openDataConfig = _context5.sent;
|
|
425
|
+
_context5.next = 16;
|
|
426
|
+
break;
|
|
427
|
+
case 12:
|
|
428
|
+
_context5.prev = 12;
|
|
429
|
+
_context5.t0 = _context5["catch"](6);
|
|
430
|
+
console.warn('[BookingTicket] OpenData 配置加载失败,跳过 idGenerator 配置', _context5.t0);
|
|
431
|
+
return _context5.abrupt("return");
|
|
433
432
|
case 16:
|
|
433
|
+
// if (!openDataConfig) return;
|
|
434
434
|
receiptSequenceLength = this.normalizePositiveInteger((_openDataConfig = openDataConfig) === null || _openDataConfig === void 0 ? void 0 : _openDataConfig['sale.short_number_digits'], 5);
|
|
435
435
|
receiptSequenceStart = this.normalizePositiveInteger((_openDataConfig2 = openDataConfig) === null || _openDataConfig2 === void 0 ? void 0 : _openDataConfig2['sale.short_number_start_number'], 1);
|
|
436
436
|
prefix = this.normalizeIdPrefix((_openDataConfig3 = openDataConfig) === null || _openDataConfig3 === void 0 ? void 0 : _openDataConfig3['sale.short_number_prefix'], '');
|
|
@@ -477,7 +477,7 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
|
|
|
477
477
|
case "end":
|
|
478
478
|
return _context5.stop();
|
|
479
479
|
}
|
|
480
|
-
}, _callee5, this, [[
|
|
480
|
+
}, _callee5, this, [[6, 12], [30, 35]]);
|
|
481
481
|
}));
|
|
482
482
|
function configureIdGeneratorFromOpenData() {
|
|
483
483
|
return _configureIdGeneratorFromOpenData.apply(this, arguments);
|
|
@@ -63,8 +63,19 @@ export declare class UnifiedBookingSalesImpl extends BookingTicket {
|
|
|
63
63
|
private openDataTarget;
|
|
64
64
|
private loadOpenDataInFlight;
|
|
65
65
|
private loadOpenDataInFlightTarget;
|
|
66
|
+
protected getSubmitOrderSalesChannel(): string;
|
|
66
67
|
protected isSessionStoragePersistEnabled(): boolean;
|
|
67
68
|
protected shouldUseSessionStorageForSubModule(moduleName?: string): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* 读取与当前 cacheId 同分桶的 Solution 会话状态。
|
|
71
|
+
* 该状态独立于 otherParams,适合页面皮肤保存短生命周期 UI 状态。
|
|
72
|
+
*/
|
|
73
|
+
getSessionStateValue<T = unknown>(key: string): T | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* 写入与当前 cacheId 同分桶的 Solution 会话状态。
|
|
76
|
+
* value 为 undefined 时删除该 key;存储失败不阻断业务流程。
|
|
77
|
+
*/
|
|
78
|
+
setSessionStateValue(key: string, value: unknown): void;
|
|
68
79
|
/**
|
|
69
80
|
* Kiosk 不能把已收款订单留在本地等待重试:默认直接等待云端 checkout。
|
|
70
81
|
* 兼容仍需要 WebPOS 待同步模式的入口可显式传 checkoutSyncTaskEnabled: true。
|
|
@@ -40,6 +40,9 @@ import { BookingTicket } from "../BookingTicket";
|
|
|
40
40
|
export * from "./types";
|
|
41
41
|
var OPEN_DATA_SECTION_CODES = ['sale', 'reservation', 'fulfillment', 'menu', 'workflow'];
|
|
42
42
|
var OPEN_DATA_CACHE_TTL = 5 * 60 * 1000;
|
|
43
|
+
function isRecord(value) {
|
|
44
|
+
return !!value && _typeof(value) === 'object' && !Array.isArray(value);
|
|
45
|
+
}
|
|
43
46
|
function pickLocalizedText(value) {
|
|
44
47
|
if (!value) return undefined;
|
|
45
48
|
if (typeof value === 'string') return value;
|
|
@@ -520,10 +523,17 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
520
523
|
return _this;
|
|
521
524
|
}
|
|
522
525
|
_createClass(UnifiedBookingSalesImpl, [{
|
|
526
|
+
key: "getSubmitOrderSalesChannel",
|
|
527
|
+
value: function getSubmitOrderSalesChannel() {
|
|
528
|
+
var _this$otherParams$cha, _this$otherParams;
|
|
529
|
+
var channel = String((_this$otherParams$cha = (_this$otherParams = this.otherParams) === null || _this$otherParams === void 0 ? void 0 : _this$otherParams.channel) !== null && _this$otherParams$cha !== void 0 ? _this$otherParams$cha : '').trim();
|
|
530
|
+
return channel || _get(_getPrototypeOf(UnifiedBookingSalesImpl.prototype), "getSubmitOrderSalesChannel", this).call(this);
|
|
531
|
+
}
|
|
532
|
+
}, {
|
|
523
533
|
key: "isSessionStoragePersistEnabled",
|
|
524
534
|
value: function isSessionStoragePersistEnabled() {
|
|
525
|
-
var _this$
|
|
526
|
-
return Boolean(this.cacheId && ((_this$
|
|
535
|
+
var _this$otherParams2;
|
|
536
|
+
return Boolean(this.cacheId && ((_this$otherParams2 = this.otherParams) === null || _this$otherParams2 === void 0 ? void 0 : _this$otherParams2.enableSessionStoragePersist) === true);
|
|
527
537
|
}
|
|
528
538
|
}, {
|
|
529
539
|
key: "shouldUseSessionStorageForSubModule",
|
|
@@ -531,6 +541,49 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
531
541
|
return this.isSessionStoragePersistEnabled() && moduleName === 'order';
|
|
532
542
|
}
|
|
533
543
|
|
|
544
|
+
/**
|
|
545
|
+
* 读取与当前 cacheId 同分桶的 Solution 会话状态。
|
|
546
|
+
* 该状态独立于 otherParams,适合页面皮肤保存短生命周期 UI 状态。
|
|
547
|
+
*/
|
|
548
|
+
}, {
|
|
549
|
+
key: "getSessionStateValue",
|
|
550
|
+
value: function getSessionStateValue(key) {
|
|
551
|
+
if (!key || !this.isSessionStoragePersistEnabled()) return undefined;
|
|
552
|
+
var cacheData = this.readSessionCacheData();
|
|
553
|
+
var solutionCache = cacheData === null || cacheData === void 0 ? void 0 : cacheData[this.name];
|
|
554
|
+
if (!isRecord(solutionCache) || !isRecord(solutionCache.sessionState)) {
|
|
555
|
+
return undefined;
|
|
556
|
+
}
|
|
557
|
+
return solutionCache.sessionState[key];
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* 写入与当前 cacheId 同分桶的 Solution 会话状态。
|
|
562
|
+
* value 为 undefined 时删除该 key;存储失败不阻断业务流程。
|
|
563
|
+
*/
|
|
564
|
+
}, {
|
|
565
|
+
key: "setSessionStateValue",
|
|
566
|
+
value: function setSessionStateValue(key, value) {
|
|
567
|
+
if (!key || !this.isSessionStoragePersistEnabled()) return;
|
|
568
|
+
var cacheData = this.readSessionCacheData();
|
|
569
|
+
var solutionCache = cacheData === null || cacheData === void 0 ? void 0 : cacheData[this.name];
|
|
570
|
+
var currentSessionState = isRecord(solutionCache) && isRecord(solutionCache.sessionState) ? solutionCache.sessionState : {};
|
|
571
|
+
var nextSessionState = _objectSpread({}, currentSessionState);
|
|
572
|
+
if (value === undefined) {
|
|
573
|
+
delete nextSessionState[key];
|
|
574
|
+
} else {
|
|
575
|
+
nextSessionState[key] = value;
|
|
576
|
+
}
|
|
577
|
+
this.checkSaveCache({
|
|
578
|
+
cacheId: this.cacheId,
|
|
579
|
+
fatherModule: this.name,
|
|
580
|
+
store: {
|
|
581
|
+
sessionState: nextSessionState
|
|
582
|
+
},
|
|
583
|
+
cacheKey: ['sessionState']
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
|
|
534
587
|
/**
|
|
535
588
|
* Kiosk 不能把已收款订单留在本地等待重试:默认直接等待云端 checkout。
|
|
536
589
|
* 兼容仍需要 WebPOS 待同步模式的入口可显式传 checkoutSyncTaskEnabled: true。
|
|
@@ -538,8 +591,8 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
538
591
|
}, {
|
|
539
592
|
key: "shouldUseCheckoutSyncTask",
|
|
540
593
|
value: function shouldUseCheckoutSyncTask() {
|
|
541
|
-
var _this$
|
|
542
|
-
var configured = (_this$
|
|
594
|
+
var _this$otherParams3;
|
|
595
|
+
var configured = (_this$otherParams3 = this.otherParams) === null || _this$otherParams3 === void 0 ? void 0 : _this$otherParams3.checkoutSyncTaskEnabled;
|
|
543
596
|
return typeof configured === 'boolean' ? configured : false;
|
|
544
597
|
}
|
|
545
598
|
|
|
@@ -697,8 +750,8 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
697
750
|
}, {
|
|
698
751
|
key: "isAuthenticatedCustomerUserPlatform",
|
|
699
752
|
value: function isAuthenticatedCustomerUserPlatform() {
|
|
700
|
-
var _this$
|
|
701
|
-
var platform = String(((_this$
|
|
753
|
+
var _this$otherParams4;
|
|
754
|
+
var platform = String(((_this$otherParams4 = this.otherParams) === null || _this$otherParams4 === void 0 ? void 0 : _this$otherParams4.platform) || '').toLowerCase();
|
|
702
755
|
return platform === 'pc' || platform === 'h5';
|
|
703
756
|
}
|
|
704
757
|
}, {
|
|
@@ -877,13 +930,13 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
877
930
|
key: "getOpenData",
|
|
878
931
|
value: function () {
|
|
879
932
|
var _getOpenData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
|
|
880
|
-
var _this$
|
|
933
|
+
var _this$otherParams5, _this$otherParams6, _this$store$openData;
|
|
881
934
|
var businessCode, channel, target, cachedData;
|
|
882
935
|
return _regeneratorRuntime().wrap(function _callee6$(_context6) {
|
|
883
936
|
while (1) switch (_context6.prev = _context6.next) {
|
|
884
937
|
case 0:
|
|
885
|
-
businessCode = String(((_this$
|
|
886
|
-
channel = String(((_this$
|
|
938
|
+
businessCode = String(((_this$otherParams5 = this.otherParams) === null || _this$otherParams5 === void 0 ? void 0 : _this$otherParams5.businessCode) || '').trim();
|
|
939
|
+
channel = String(((_this$otherParams6 = this.otherParams) === null || _this$otherParams6 === void 0 ? void 0 : _this$otherParams6.channel) || '').trim();
|
|
887
940
|
if (!(!businessCode || !channel)) {
|
|
888
941
|
_context6.next = 4;
|
|
889
942
|
break;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
-
mod
|
|
26
|
-
));
|
|
27
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
-
|
|
29
|
-
// src/model/strategy/adapter/promotion/index.ts
|
|
30
|
-
var promotion_exports = {};
|
|
31
|
-
__export(promotion_exports, {
|
|
32
|
-
BUY_X_GET_Y_FREE_STRATEGY: () => import_examples.BUY_X_GET_Y_FREE_STRATEGY,
|
|
33
|
-
ITEM_REWARD_STRATEGY: () => import_examples.ITEM_REWARD_STRATEGY,
|
|
34
|
-
PromotionAdapter: () => import_adapter.PromotionAdapter,
|
|
35
|
-
PromotionEvaluator: () => import_evaluator.PromotionEvaluator,
|
|
36
|
-
X_ITEMS_FOR_Y_PRICE_STRATEGY: () => import_examples.X_ITEMS_FOR_Y_PRICE_STRATEGY,
|
|
37
|
-
default: () => import_adapter2.default
|
|
38
|
-
});
|
|
39
|
-
module.exports = __toCommonJS(promotion_exports);
|
|
40
|
-
var import_evaluator = require("./evaluator");
|
|
41
|
-
var import_adapter = require("./adapter");
|
|
42
|
-
var import_adapter2 = __toESM(require("./adapter"));
|
|
43
|
-
var import_examples = require("./examples");
|
|
44
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
45
|
-
0 && (module.exports = {
|
|
46
|
-
BUY_X_GET_Y_FREE_STRATEGY,
|
|
47
|
-
ITEM_REWARD_STRATEGY,
|
|
48
|
-
PromotionAdapter,
|
|
49
|
-
PromotionEvaluator,
|
|
50
|
-
X_ITEMS_FOR_Y_PRICE_STRATEGY
|
|
51
|
-
});
|
|
@@ -237,6 +237,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
237
237
|
private sanitizeOrderProductForTempOrder;
|
|
238
238
|
private sanitizeTempOrderProducts;
|
|
239
239
|
private ensureExtend;
|
|
240
|
+
private repairDuplicateProductLineIdentities;
|
|
240
241
|
private captureProductRuntime;
|
|
241
242
|
private createLinkedProductAndBooking;
|
|
242
243
|
/**
|
|
@@ -497,7 +498,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
497
498
|
generateIdempotencyToken(): string;
|
|
498
499
|
syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
|
|
499
500
|
createOrder(params: CommitOrderParams['query']): {
|
|
500
|
-
type: "
|
|
501
|
+
type: "appointment_booking" | "virtual";
|
|
501
502
|
platform: string;
|
|
502
503
|
sales_channel: string;
|
|
503
504
|
order_sales_channel: string;
|
|
@@ -694,6 +694,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
694
694
|
};
|
|
695
695
|
})
|
|
696
696
|
);
|
|
697
|
+
this.repairDuplicateProductLineIdentities(tempOrder);
|
|
697
698
|
}
|
|
698
699
|
if (result == null ? void 0 : result.discountList) {
|
|
699
700
|
OrderModule.populateSavedAmounts(
|
|
@@ -1931,6 +1932,23 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1931
1932
|
}
|
|
1932
1933
|
return tempOrder._extend;
|
|
1933
1934
|
}
|
|
1935
|
+
repairDuplicateProductLineIdentities(tempOrder) {
|
|
1936
|
+
var _a;
|
|
1937
|
+
const result = (0, import_orderCollectionIdentity.repairDuplicateProductLineIdentities)(
|
|
1938
|
+
tempOrder.products,
|
|
1939
|
+
(_a = tempOrder._extend) == null ? void 0 : _a.productsByUid
|
|
1940
|
+
);
|
|
1941
|
+
if (!result.repairs.length)
|
|
1942
|
+
return;
|
|
1943
|
+
tempOrder.products = result.products;
|
|
1944
|
+
if (result.productsByUid) {
|
|
1945
|
+
this.ensureExtend(tempOrder).productsByUid = result.productsByUid;
|
|
1946
|
+
}
|
|
1947
|
+
this.logWarning("Repaired duplicate product line identities", {
|
|
1948
|
+
repairCount: result.repairs.length,
|
|
1949
|
+
repairs: result.repairs
|
|
1950
|
+
});
|
|
1951
|
+
}
|
|
1934
1952
|
captureProductRuntime(tempOrder, rawProduct, normalizedProduct, existedUid) {
|
|
1935
1953
|
var _a;
|
|
1936
1954
|
const uid = existedUid || this.getProductUid(normalizedProduct);
|
|
@@ -3484,6 +3502,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
3484
3502
|
product_bundle
|
|
3485
3503
|
} = params;
|
|
3486
3504
|
const tempOrder = this.ensureTempOrder();
|
|
3505
|
+
this.repairDuplicateProductLineIdentities(tempOrder);
|
|
3487
3506
|
const identityLookup = {
|
|
3488
3507
|
product_id,
|
|
3489
3508
|
product_variant_id
|
|
@@ -3594,6 +3613,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
3594
3613
|
async removeProductsFromOrder(identities) {
|
|
3595
3614
|
var _a, _b, _c, _d;
|
|
3596
3615
|
const tempOrder = this.ensureTempOrder();
|
|
3616
|
+
this.repairDuplicateProductLineIdentities(tempOrder);
|
|
3597
3617
|
if (!identities.length) {
|
|
3598
3618
|
return tempOrder.products;
|
|
3599
3619
|
}
|
|
@@ -4300,24 +4320,39 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
4300
4320
|
* 例如数组字段、商品行唯一值、价格 metadata、summary 派生状态和 _extend。
|
|
4301
4321
|
*/
|
|
4302
4322
|
async hydrateTempOrderFromRecord(record, options) {
|
|
4303
|
-
var _a, _b, _c, _d, _e;
|
|
4323
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4304
4324
|
const sourceRaw = record && typeof record === "object" && record.data && record.order_id == null ? record.data : record || {};
|
|
4325
|
+
const duplicateProductIdentityRepair = (0, import_orderCollectionIdentity.repairDuplicateProductLineIdentities)(
|
|
4326
|
+
Array.isArray(sourceRaw.products) ? sourceRaw.products : [],
|
|
4327
|
+
(_a = sourceRaw._extend) == null ? void 0 : _a.productsByUid
|
|
4328
|
+
);
|
|
4329
|
+
const duplicateIdentityReadySource = duplicateProductIdentityRepair.repairs.length ? {
|
|
4330
|
+
...sourceRaw,
|
|
4331
|
+
products: duplicateProductIdentityRepair.products,
|
|
4332
|
+
...duplicateProductIdentityRepair.productsByUid ? {
|
|
4333
|
+
_extend: {
|
|
4334
|
+
...sourceRaw._extend || {},
|
|
4335
|
+
productsByUid: duplicateProductIdentityRepair.productsByUid
|
|
4336
|
+
}
|
|
4337
|
+
} : {}
|
|
4338
|
+
} : sourceRaw;
|
|
4305
4339
|
const identityReadySource = this.seedAnonymousBookingUidsFromProducts(
|
|
4306
|
-
|
|
4340
|
+
duplicateIdentityReadySource
|
|
4307
4341
|
);
|
|
4308
4342
|
const normalizedCollections = (0, import_orderCollectionIdentity.normalizeOrderCollections)(identityReadySource);
|
|
4309
4343
|
const raw = normalizedCollections.order;
|
|
4310
|
-
const hasIdentityChanges = Object.values(normalizedCollections.stats).some(
|
|
4344
|
+
const hasIdentityChanges = duplicateProductIdentityRepair.repairs.length > 0 || Object.values(normalizedCollections.stats).some(
|
|
4311
4345
|
(stats) => stats.backfilledUidCount > 0 || stats.collapsedDuplicateCount > 0 || stats.uidConflictCount > 0 || stats.anonymousRowCount > 0
|
|
4312
4346
|
);
|
|
4313
4347
|
if (hasIdentityChanges) {
|
|
4314
4348
|
const identityLogMetadata = {
|
|
4315
4349
|
collections: normalizedCollections.stats,
|
|
4316
|
-
uidRemapCount: normalizedCollections.uidRemaps.length
|
|
4350
|
+
uidRemapCount: normalizedCollections.uidRemaps.length,
|
|
4351
|
+
duplicateProductUidRepairCount: duplicateProductIdentityRepair.repairs.length
|
|
4317
4352
|
};
|
|
4318
4353
|
const hasIdentityWarnings = Object.values(normalizedCollections.stats).some(
|
|
4319
4354
|
(stats) => stats.uidConflictCount > 0 || stats.anonymousRowCount > 0
|
|
4320
|
-
);
|
|
4355
|
+
) || duplicateProductIdentityRepair.repairs.length > 0;
|
|
4321
4356
|
if (hasIdentityWarnings) {
|
|
4322
4357
|
this.logWarning(
|
|
4323
4358
|
"Normalized hydrated order collection identities",
|
|
@@ -4348,10 +4383,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
4348
4383
|
nextTempOrder.discount_list = restoredSessionDiscounts;
|
|
4349
4384
|
this.store.summary = (0, import_utils.createEmptySummary)();
|
|
4350
4385
|
this.store.lastOrderInfo = void 0;
|
|
4351
|
-
await ((
|
|
4386
|
+
await ((_b = this.store.discount) == null ? void 0 : _b.setOriginalDiscountList(
|
|
4352
4387
|
(0, import_lodash_es.cloneDeep)(restoredSessionDiscounts)
|
|
4353
4388
|
));
|
|
4354
|
-
await ((
|
|
4389
|
+
await ((_c = this.store.discount) == null ? void 0 : _c.setDiscountList(
|
|
4355
4390
|
(0, import_lodash_es.cloneDeep)(restoredSessionDiscounts)
|
|
4356
4391
|
));
|
|
4357
4392
|
if (options == null ? void 0 : options.recalcOnHydrate) {
|
|
@@ -4394,7 +4429,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
4394
4429
|
this.store.syncState = "local";
|
|
4395
4430
|
}
|
|
4396
4431
|
const hydratedEditDiscounts = this.collectHydratedEditDiscounts(nextTempOrder.products);
|
|
4397
|
-
const currentDiscounts = typeof ((
|
|
4432
|
+
const currentDiscounts = typeof ((_d = this.store.discount) == null ? void 0 : _d.getDiscountList) === "function" ? this.store.discount.getDiscountList() || [] : [];
|
|
4398
4433
|
const currentScanDiscounts = currentDiscounts.filter((discount) => discount == null ? void 0 : discount.isScan);
|
|
4399
4434
|
const hydratedDiscountIds = new Set(
|
|
4400
4435
|
hydratedEditDiscounts.map((discount) => discount == null ? void 0 : discount.id)
|
|
@@ -4412,8 +4447,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
4412
4447
|
nextTempOrder.products,
|
|
4413
4448
|
nextDiscounts
|
|
4414
4449
|
);
|
|
4415
|
-
await ((
|
|
4416
|
-
await ((
|
|
4450
|
+
await ((_e = this.store.discount) == null ? void 0 : _e.setOriginalDiscountList(nextDiscounts));
|
|
4451
|
+
await ((_f = this.store.discount) == null ? void 0 : _f.setDiscountList(nextDiscounts));
|
|
4417
4452
|
}
|
|
4418
4453
|
if (options == null ? void 0 : options.recalcOnHydrate) {
|
|
4419
4454
|
await this.recalculateSummary({ createIfMissing: false });
|
|
@@ -24,6 +24,16 @@ export interface NormalizeOrderCollectionsResult<T> {
|
|
|
24
24
|
stats: Record<OrderCollectionKind, OrderCollectionIdentityStats>;
|
|
25
25
|
uidRemaps: OrderCollectionUidRemap[];
|
|
26
26
|
}
|
|
27
|
+
export interface ProductLineIdentityRepair {
|
|
28
|
+
index: number;
|
|
29
|
+
from: string;
|
|
30
|
+
to: string;
|
|
31
|
+
}
|
|
32
|
+
export interface RepairDuplicateProductLineIdentitiesResult<T> {
|
|
33
|
+
products: T[];
|
|
34
|
+
productsByUid?: Record<string, Record<string, any>>;
|
|
35
|
+
repairs: ProductLineIdentityRepair[];
|
|
36
|
+
}
|
|
27
37
|
export declare function createUuidV4(): string;
|
|
28
38
|
export declare function isBlankOrderCollectionIdentity(value: unknown): boolean;
|
|
29
39
|
export declare function getOrderCollectionPersistentId(kind: OrderCollectionKind, item: unknown): string | null;
|
|
@@ -31,6 +41,11 @@ export declare function getOrderCollectionUid(kind: OrderCollectionKind, item: u
|
|
|
31
41
|
export declare function buildOrderCollectionFallbackUid(kind: OrderCollectionKind, persistentId: string | number): string;
|
|
32
42
|
export declare function getOrderCollectionReferenceUid(kind: OrderCollectionKind, item: unknown): string | null;
|
|
33
43
|
export declare function setOrderCollectionUid<T>(kind: OrderCollectionKind, item: T, uid: string): T;
|
|
44
|
+
/**
|
|
45
|
+
* Rules 会把同一商品按商品券拆成多条真实订单行。拆行结果会继承原商品 UID,
|
|
46
|
+
* 因此必须在通用 collection normalization 之前为后续行派生稳定身份,避免被折叠。
|
|
47
|
+
*/
|
|
48
|
+
export declare function repairDuplicateProductLineIdentities<T extends Record<string, any>>(products: T[] | null | undefined, productsByUid?: Record<string, Record<string, any>> | null): RepairDuplicateProductLineIdentitiesResult<T>;
|
|
34
49
|
/**
|
|
35
50
|
* 持久化行 ID 是服务端事实主键;只有至少一侧尚未持久化时,才允许用 runtime UID 对齐。
|
|
36
51
|
*/
|
|
@@ -30,6 +30,7 @@ __export(orderCollectionIdentity_exports, {
|
|
|
30
30
|
mergeOrderCollectionItems: () => mergeOrderCollectionItems,
|
|
31
31
|
normalizeOrderCollection: () => normalizeOrderCollection,
|
|
32
32
|
normalizeOrderCollections: () => normalizeOrderCollections,
|
|
33
|
+
repairDuplicateProductLineIdentities: () => repairDuplicateProductLineIdentities,
|
|
33
34
|
setOrderCollectionUid: () => setOrderCollectionUid
|
|
34
35
|
});
|
|
35
36
|
module.exports = __toCommonJS(orderCollectionIdentity_exports);
|
|
@@ -105,6 +106,74 @@ function setOrderCollectionUid(kind, item, uid) {
|
|
|
105
106
|
delete record[uidField];
|
|
106
107
|
return record;
|
|
107
108
|
}
|
|
109
|
+
function getGoodPassResourceId(product) {
|
|
110
|
+
var _a;
|
|
111
|
+
const goodPass = (product.discount_list || []).find((item) => {
|
|
112
|
+
var _a2, _b;
|
|
113
|
+
const type = (item == null ? void 0 : item.type) || (item == null ? void 0 : item.tag) || ((_a2 = item == null ? void 0 : item.discount) == null ? void 0 : _a2.type) || ((_b = item == null ? void 0 : item.discount) == null ? void 0 : _b.tag);
|
|
114
|
+
return type === "good_pass";
|
|
115
|
+
});
|
|
116
|
+
if (!goodPass)
|
|
117
|
+
return null;
|
|
118
|
+
const resourceId = ((_a = goodPass.discount) == null ? void 0 : _a.resource_id) ?? goodPass.resource_id ?? goodPass.discount_id ?? goodPass.id;
|
|
119
|
+
return isBlankOrderCollectionIdentity(resourceId) ? null : String(resourceId);
|
|
120
|
+
}
|
|
121
|
+
function buildSplitProductUid(originalUid, product, duplicateOrdinal) {
|
|
122
|
+
const encodedOriginalUid = encodeURIComponent(originalUid);
|
|
123
|
+
const resourceId = getGoodPassResourceId(product);
|
|
124
|
+
if (resourceId) {
|
|
125
|
+
return `os-split:product:${encodedOriginalUid}:good-pass:${encodeURIComponent(resourceId)}:${duplicateOrdinal}`;
|
|
126
|
+
}
|
|
127
|
+
return `os-split:product:${encodedOriginalUid}:duplicate:${duplicateOrdinal}`;
|
|
128
|
+
}
|
|
129
|
+
function repairDuplicateProductLineIdentities(products, productsByUid) {
|
|
130
|
+
const repairedProducts = (0, import_lodash_es.cloneDeep)(products || []);
|
|
131
|
+
const repairedProductsByUid = productsByUid ? (0, import_lodash_es.cloneDeep)(productsByUid) : void 0;
|
|
132
|
+
const occupiedUids = new Set(
|
|
133
|
+
repairedProducts.map((product) => getOrderCollectionUid("product", product)).filter((uid) => Boolean(uid))
|
|
134
|
+
);
|
|
135
|
+
Object.keys(repairedProductsByUid || {}).forEach((uid) => occupiedUids.add(uid));
|
|
136
|
+
const occurrences = /* @__PURE__ */ new Map();
|
|
137
|
+
const repairs = [];
|
|
138
|
+
repairedProducts.forEach((product, index) => {
|
|
139
|
+
const originalUid = getOrderCollectionUid("product", product);
|
|
140
|
+
if (!originalUid)
|
|
141
|
+
return;
|
|
142
|
+
const occurrence = (occurrences.get(originalUid) || 0) + 1;
|
|
143
|
+
occurrences.set(originalUid, occurrence);
|
|
144
|
+
if (occurrence === 1)
|
|
145
|
+
return;
|
|
146
|
+
const duplicateOrdinal = occurrence - 1;
|
|
147
|
+
const baseCandidate = buildSplitProductUid(
|
|
148
|
+
originalUid,
|
|
149
|
+
product,
|
|
150
|
+
duplicateOrdinal
|
|
151
|
+
);
|
|
152
|
+
let nextUid = baseCandidate;
|
|
153
|
+
let conflictOrdinal = 1;
|
|
154
|
+
while (occupiedUids.has(nextUid)) {
|
|
155
|
+
nextUid = `${baseCandidate}:conflict:${conflictOrdinal}`;
|
|
156
|
+
conflictOrdinal += 1;
|
|
157
|
+
}
|
|
158
|
+
const repairedProduct = setOrderCollectionUid("product", product, nextUid);
|
|
159
|
+
repairedProduct.identity_key = nextUid;
|
|
160
|
+
repairedProducts[index] = repairedProduct;
|
|
161
|
+
occupiedUids.add(nextUid);
|
|
162
|
+
repairs.push({ index, from: originalUid, to: nextUid });
|
|
163
|
+
const runtimeSource = repairedProductsByUid == null ? void 0 : repairedProductsByUid[originalUid];
|
|
164
|
+
if (runtimeSource && repairedProductsByUid) {
|
|
165
|
+
repairedProductsByUid[nextUid] = {
|
|
166
|
+
...(0, import_lodash_es.cloneDeep)(runtimeSource),
|
|
167
|
+
...runtimeSource.rowKey !== void 0 ? { rowKey: nextUid } : {}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
return {
|
|
172
|
+
products: repairedProducts,
|
|
173
|
+
...repairedProductsByUid ? { productsByUid: repairedProductsByUid } : {},
|
|
174
|
+
repairs
|
|
175
|
+
};
|
|
176
|
+
}
|
|
108
177
|
function isSameOrderCollectionItem(kind, left, right) {
|
|
109
178
|
const leftPersistentId = getOrderCollectionPersistentId(kind, left);
|
|
110
179
|
const rightPersistentId = getOrderCollectionPersistentId(kind, right);
|
|
@@ -414,5 +483,6 @@ function normalizeOrderCollections(sourceOrder, options) {
|
|
|
414
483
|
mergeOrderCollectionItems,
|
|
415
484
|
normalizeOrderCollection,
|
|
416
485
|
normalizeOrderCollections,
|
|
486
|
+
repairDuplicateProductLineIdentities,
|
|
417
487
|
setOrderCollectionUid
|
|
418
488
|
});
|
|
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
326
326
|
date: string;
|
|
327
327
|
status: string;
|
|
328
328
|
week: string;
|
|
329
|
-
weekNum: 0 |
|
|
329
|
+
weekNum: 0 | 5 | 2 | 1 | 6 | 4 | 3;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -447,7 +447,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
447
447
|
* 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
|
|
448
448
|
* 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
|
|
449
449
|
*/
|
|
450
|
-
decideAddProduct(item: any, options?: Partial<AddProductDecideContext>):
|
|
450
|
+
decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
|
|
451
|
+
action: "reloadCatalog";
|
|
452
|
+
} | {
|
|
453
|
+
action: "add";
|
|
454
|
+
cacheItem: any;
|
|
455
|
+
} | {
|
|
456
|
+
action: "requiresDetail";
|
|
457
|
+
payload: AddProductRequiresDetailPayload;
|
|
458
|
+
} | {
|
|
459
|
+
action: "requiresBookingEdit";
|
|
460
|
+
cacheItem: any;
|
|
461
|
+
payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
|
|
462
|
+
};
|
|
451
463
|
/** 规格弹窗 callback 后的第二段决策。 */
|
|
452
464
|
decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
|
|
453
465
|
/**
|
|
@@ -242,6 +242,11 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
|
|
|
242
242
|
}
|
|
243
243
|
async configureIdGeneratorFromOpenData() {
|
|
244
244
|
this.setPaymentNumberDevicePrefix(null);
|
|
245
|
+
const idGenerator = this.getIdGeneratorPlugin();
|
|
246
|
+
if (!(idGenerator == null ? void 0 : idGenerator.configure)) {
|
|
247
|
+
console.warn("[BookingTicket] idGenerator 插件不可用,跳过配置");
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
245
250
|
let openDataConfig = null;
|
|
246
251
|
try {
|
|
247
252
|
openDataConfig = await this.loadOpenDataConfig();
|
|
@@ -249,11 +254,6 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
|
|
|
249
254
|
console.warn("[BookingTicket] OpenData 配置加载失败,跳过 idGenerator 配置", error);
|
|
250
255
|
return;
|
|
251
256
|
}
|
|
252
|
-
const idGenerator = this.getIdGeneratorPlugin();
|
|
253
|
-
if (!(idGenerator == null ? void 0 : idGenerator.configure)) {
|
|
254
|
-
console.warn("[BookingTicket] idGenerator 插件不可用,跳过配置");
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
257
|
const receiptSequenceLength = this.normalizePositiveInteger(
|
|
258
258
|
openDataConfig == null ? void 0 : openDataConfig["sale.short_number_digits"],
|
|
259
259
|
5
|
|
@@ -63,8 +63,19 @@ export declare class UnifiedBookingSalesImpl extends BookingTicket {
|
|
|
63
63
|
private openDataTarget;
|
|
64
64
|
private loadOpenDataInFlight;
|
|
65
65
|
private loadOpenDataInFlightTarget;
|
|
66
|
+
protected getSubmitOrderSalesChannel(): string;
|
|
66
67
|
protected isSessionStoragePersistEnabled(): boolean;
|
|
67
68
|
protected shouldUseSessionStorageForSubModule(moduleName?: string): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* 读取与当前 cacheId 同分桶的 Solution 会话状态。
|
|
71
|
+
* 该状态独立于 otherParams,适合页面皮肤保存短生命周期 UI 状态。
|
|
72
|
+
*/
|
|
73
|
+
getSessionStateValue<T = unknown>(key: string): T | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* 写入与当前 cacheId 同分桶的 Solution 会话状态。
|
|
76
|
+
* value 为 undefined 时删除该 key;存储失败不阻断业务流程。
|
|
77
|
+
*/
|
|
78
|
+
setSessionStateValue(key: string, value: unknown): void;
|
|
68
79
|
/**
|
|
69
80
|
* Kiosk 不能把已收款订单留在本地等待重试:默认直接等待云端 checkout。
|
|
70
81
|
* 兼容仍需要 WebPOS 待同步模式的入口可显式传 checkoutSyncTaskEnabled: true。
|
|
@@ -49,6 +49,9 @@ var import_BookingTicket = require("../BookingTicket");
|
|
|
49
49
|
__reExport(UnifiedBookingSales_exports, require("./types"), module.exports);
|
|
50
50
|
var OPEN_DATA_SECTION_CODES = ["sale", "reservation", "fulfillment", "menu", "workflow"];
|
|
51
51
|
var OPEN_DATA_CACHE_TTL = 5 * 60 * 1e3;
|
|
52
|
+
function isRecord(value) {
|
|
53
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
54
|
+
}
|
|
52
55
|
function pickLocalizedText(value) {
|
|
53
56
|
if (!value)
|
|
54
57
|
return void 0;
|
|
@@ -469,6 +472,11 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
|
|
|
469
472
|
this.loadOpenDataInFlight = null;
|
|
470
473
|
this.loadOpenDataInFlightTarget = null;
|
|
471
474
|
}
|
|
475
|
+
getSubmitOrderSalesChannel() {
|
|
476
|
+
var _a;
|
|
477
|
+
const channel = String(((_a = this.otherParams) == null ? void 0 : _a.channel) ?? "").trim();
|
|
478
|
+
return channel || super.getSubmitOrderSalesChannel();
|
|
479
|
+
}
|
|
472
480
|
isSessionStoragePersistEnabled() {
|
|
473
481
|
var _a;
|
|
474
482
|
return Boolean(
|
|
@@ -478,6 +486,43 @@ var UnifiedBookingSalesImpl = class extends import_BookingTicket.BookingTicket {
|
|
|
478
486
|
shouldUseSessionStorageForSubModule(moduleName) {
|
|
479
487
|
return this.isSessionStoragePersistEnabled() && moduleName === "order";
|
|
480
488
|
}
|
|
489
|
+
/**
|
|
490
|
+
* 读取与当前 cacheId 同分桶的 Solution 会话状态。
|
|
491
|
+
* 该状态独立于 otherParams,适合页面皮肤保存短生命周期 UI 状态。
|
|
492
|
+
*/
|
|
493
|
+
getSessionStateValue(key) {
|
|
494
|
+
if (!key || !this.isSessionStoragePersistEnabled())
|
|
495
|
+
return void 0;
|
|
496
|
+
const cacheData = this.readSessionCacheData();
|
|
497
|
+
const solutionCache = cacheData == null ? void 0 : cacheData[this.name];
|
|
498
|
+
if (!isRecord(solutionCache) || !isRecord(solutionCache.sessionState)) {
|
|
499
|
+
return void 0;
|
|
500
|
+
}
|
|
501
|
+
return solutionCache.sessionState[key];
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* 写入与当前 cacheId 同分桶的 Solution 会话状态。
|
|
505
|
+
* value 为 undefined 时删除该 key;存储失败不阻断业务流程。
|
|
506
|
+
*/
|
|
507
|
+
setSessionStateValue(key, value) {
|
|
508
|
+
if (!key || !this.isSessionStoragePersistEnabled())
|
|
509
|
+
return;
|
|
510
|
+
const cacheData = this.readSessionCacheData();
|
|
511
|
+
const solutionCache = cacheData == null ? void 0 : cacheData[this.name];
|
|
512
|
+
const currentSessionState = isRecord(solutionCache) && isRecord(solutionCache.sessionState) ? solutionCache.sessionState : {};
|
|
513
|
+
const nextSessionState = { ...currentSessionState };
|
|
514
|
+
if (value === void 0) {
|
|
515
|
+
delete nextSessionState[key];
|
|
516
|
+
} else {
|
|
517
|
+
nextSessionState[key] = value;
|
|
518
|
+
}
|
|
519
|
+
this.checkSaveCache({
|
|
520
|
+
cacheId: this.cacheId,
|
|
521
|
+
fatherModule: this.name,
|
|
522
|
+
store: { sessionState: nextSessionState },
|
|
523
|
+
cacheKey: ["sessionState"]
|
|
524
|
+
});
|
|
525
|
+
}
|
|
481
526
|
/**
|
|
482
527
|
* Kiosk 不能把已收款订单留在本地等待重试:默认直接等待云端 checkout。
|
|
483
528
|
* 兼容仍需要 WebPOS 待同步模式的入口可显式传 checkoutSyncTaskEnabled: true。
|