@pisell/pisellos 0.10.6 → 0.10.8
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/promotion/index.js +9 -0
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +12 -10
- package/dist/modules/Order/index.d.ts +14 -6
- package/dist/modules/Order/index.js +373 -246
- package/dist/modules/Order/types.d.ts +26 -3
- package/dist/modules/Order/types.js +11 -0
- package/dist/modules/Order/utils/discountProductLineIdentity.d.ts +45 -0
- package/dist/modules/Order/utils/discountProductLineIdentity.js +227 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +15 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.js +75 -0
- package/dist/modules/Rules/index.js +125 -52
- package/dist/modules/SalesSummary/utils.js +7 -1
- package/dist/server/index.d.ts +6 -0
- package/dist/server/index.js +810 -729
- package/dist/server/modules/order/index.d.ts +1 -0
- package/dist/server/modules/order/index.js +9 -2
- package/dist/server/modules/order/types.d.ts +1 -1
- package/dist/solution/BaseSales/index.d.ts +15 -5
- package/dist/solution/BaseSales/index.js +211 -159
- package/dist/solution/BaseSales/utils/cartPromotion.js +26 -3
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +1 -1
- package/dist/solution/BaseSales/utils.js +31 -20
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +13 -1
- package/dist/solution/BookingTicket/index.js +19 -22
- package/dist/solution/BookingTicket/types.d.ts +3 -0
- package/dist/solution/BookingTicket/utils/cartView.js +44 -32
- package/dist/solution/Sales/index.d.ts +1 -0
- package/dist/solution/Sales/index.js +16 -2
- package/dist/solution/ScanOrder/utils.js +31 -20
- package/dist/solution/UnifiedBookingSales/index.d.ts +16 -4
- package/dist/solution/UnifiedBookingSales/index.js +113 -48
- package/lib/model/strategy/adapter/promotion/index.js +0 -51
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +3 -1
- package/lib/modules/Order/index.d.ts +14 -6
- package/lib/modules/Order/index.js +192 -52
- package/lib/modules/Order/types.d.ts +26 -3
- package/lib/modules/Order/utils/discountProductLineIdentity.d.ts +45 -0
- package/lib/modules/Order/utils/discountProductLineIdentity.js +170 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +15 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.js +70 -0
- package/lib/modules/Rules/index.js +100 -20
- package/lib/modules/SalesSummary/utils.js +5 -1
- package/lib/server/index.d.ts +6 -0
- package/lib/server/index.js +51 -0
- package/lib/server/modules/order/index.d.ts +1 -0
- package/lib/server/modules/order/index.js +9 -3
- package/lib/server/modules/order/types.d.ts +1 -1
- package/lib/solution/BaseSales/index.d.ts +15 -5
- package/lib/solution/BaseSales/index.js +64 -16
- package/lib/solution/BaseSales/utils/cartPromotion.js +26 -2
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +1 -1
- package/lib/solution/BaseSales/utils.js +29 -18
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +13 -1
- package/lib/solution/BookingTicket/index.js +6 -9
- package/lib/solution/BookingTicket/types.d.ts +3 -0
- package/lib/solution/BookingTicket/utils/cartView.js +43 -30
- package/lib/solution/Sales/index.d.ts +1 -0
- package/lib/solution/Sales/index.js +15 -3
- package/lib/solution/ScanOrder/utils.js +29 -18
- package/lib/solution/UnifiedBookingSales/index.d.ts +16 -4
- package/lib/solution/UnifiedBookingSales/index.js +80 -26
- package/package.json +1 -1
|
@@ -466,13 +466,36 @@ function getProductLineNoteSignature(product) {
|
|
|
466
466
|
var uid = getOrderProductUid(product);
|
|
467
467
|
return uid ? "note:".concat(uid) : "note:".concat(normalizedNote);
|
|
468
468
|
}
|
|
469
|
+
function hasGoodPassDiscount(product) {
|
|
470
|
+
var _product$_extend;
|
|
471
|
+
var productBundle = Array.isArray(product === null || product === void 0 ? void 0 : product.product_bundle) ? product.product_bundle : [];
|
|
472
|
+
var extendedBundle = Array.isArray(product === null || product === void 0 || (_product$_extend = product._extend) === null || _product$_extend === void 0 || (_product$_extend = _product$_extend.other) === null || _product$_extend === void 0 ? void 0 : _product$_extend.bundle) ? product._extend.other.bundle : [];
|
|
473
|
+
var discountLists = [product === null || product === void 0 ? void 0 : product.discount_list].concat(_toConsumableArray(productBundle.map(function (item) {
|
|
474
|
+
return item === null || item === void 0 ? void 0 : item.discount_list;
|
|
475
|
+
})), _toConsumableArray(extendedBundle.map(function (item) {
|
|
476
|
+
return item === null || item === void 0 ? void 0 : item.discount_list;
|
|
477
|
+
})));
|
|
478
|
+
return discountLists.some(function (discountList) {
|
|
479
|
+
return Array.isArray(discountList) && discountList.some(function (item) {
|
|
480
|
+
return (item === null || item === void 0 ? void 0 : item.type) === 'good_pass' || (item === null || item === void 0 ? void 0 : item.tag) === 'good_pass';
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
}
|
|
469
484
|
|
|
470
485
|
/**
|
|
471
|
-
*
|
|
472
|
-
* 以历史行 uid 作为促销前后的行边界;新增行返回空边界,仍保留原有合并语义。
|
|
486
|
+
* 商品券、自定义商品、称重行以及编辑订单历史行都有各自的促销合并边界。
|
|
473
487
|
*/
|
|
474
488
|
function getPromotionLineMergeBoundary(product) {
|
|
475
|
-
var _product$metadata3;
|
|
489
|
+
var _product$product_sku, _product$metadata3;
|
|
490
|
+
if ((product === null || product === void 0 ? void 0 : product.product_id) === undefined || (product === null || product === void 0 ? void 0 : product.product_id) === null) {
|
|
491
|
+
return "custom:".concat(getOrderProductUid(product));
|
|
492
|
+
}
|
|
493
|
+
if (hasGoodPassDiscount(product)) {
|
|
494
|
+
return "good-pass:".concat(getOrderProductUid(product));
|
|
495
|
+
}
|
|
496
|
+
if (Number((product === null || product === void 0 || (_product$product_sku = product.product_sku) === null || _product$product_sku === void 0 ? void 0 : _product$product_sku.open_sold_weight) || 0) === 1) {
|
|
497
|
+
return "weighing:".concat(getOrderProductUid(product));
|
|
498
|
+
}
|
|
476
499
|
if ((product === null || product === void 0 || (_product$metadata3 = product.metadata) === null || _product$metadata3 === void 0 ? void 0 : _product$metadata3.is_edit_for_runtime) !== true) return '';
|
|
477
500
|
return "edit:".concat(getOrderProductUid(product));
|
|
478
501
|
}
|
|
@@ -193,7 +193,7 @@ export function transformBaseProductToOrderProduct(params) {
|
|
|
193
193
|
}
|
|
194
194
|
// 从源头补充商品多语言标题
|
|
195
195
|
var productTitle = _objectSpread(_objectSpread({}, (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.title_i18n) || {}), {}, {
|
|
196
|
-
original: (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.title) || ''
|
|
196
|
+
original: (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.original_title) || (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.title) || ''
|
|
197
197
|
});
|
|
198
198
|
return {
|
|
199
199
|
product_id: productId,
|
|
@@ -37,35 +37,46 @@ export function createEmptySummary() {
|
|
|
37
37
|
* 数组元素先按主键排序再序列化,避免顺序差异导致误判为不同行。
|
|
38
38
|
*/
|
|
39
39
|
export function buildProductLineFingerprint(productOptionItem, productBundle) {
|
|
40
|
-
var
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
40
|
+
var normalizeOptions = function normalizeOptions(options) {
|
|
41
|
+
var optionArr = Array.isArray(options) ? options : [];
|
|
42
|
+
return optionArr.map(function (item) {
|
|
43
|
+
var _ref, _item$add_price;
|
|
44
|
+
return {
|
|
45
|
+
option_group_item_id: Number(item === null || item === void 0 ? void 0 : item.option_group_item_id) || 0,
|
|
46
|
+
option_group_id: Number(item === null || item === void 0 ? void 0 : item.option_group_id) || 0,
|
|
47
|
+
num: typeof (item === null || item === void 0 ? void 0 : item.num) === 'number' && !Number.isNaN(item.num) ? Math.max(1, Math.floor(item.num)) : 1,
|
|
48
|
+
price: String((_ref = (_item$add_price = item === null || item === void 0 ? void 0 : item.add_price) !== null && _item$add_price !== void 0 ? _item$add_price : item === null || item === void 0 ? void 0 : item.price) !== null && _ref !== void 0 ? _ref : '')
|
|
49
|
+
};
|
|
50
|
+
}).sort(function (p, q) {
|
|
51
|
+
if (p.option_group_item_id !== q.option_group_item_id) {
|
|
52
|
+
return p.option_group_item_id - q.option_group_item_id;
|
|
53
|
+
}
|
|
54
|
+
if (p.option_group_id !== q.option_group_id) {
|
|
55
|
+
return p.option_group_id - q.option_group_id;
|
|
56
|
+
}
|
|
57
|
+
if (p.num !== q.num) return p.num - q.num;
|
|
58
|
+
return p.price.localeCompare(q.price);
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
var normalizedOpts = normalizeOptions(productOptionItem);
|
|
57
62
|
var bundleArr = Array.isArray(productBundle) ? productBundle : [];
|
|
58
63
|
var normalizedBundles = bundleArr.map(function (item) {
|
|
59
|
-
var _ref2, _item$bundle_id;
|
|
64
|
+
var _ref2, _item$bundle_id, _item$bundle_variant_;
|
|
60
65
|
return {
|
|
61
66
|
bundle_id: Number((_ref2 = (_item$bundle_id = item === null || item === void 0 ? void 0 : item.bundle_id) !== null && _item$bundle_id !== void 0 ? _item$bundle_id : item === null || item === void 0 ? void 0 : item.id) !== null && _ref2 !== void 0 ? _ref2 : 0) || 0,
|
|
62
67
|
product_id: Number(item === null || item === void 0 ? void 0 : item.product_id) || 0,
|
|
63
|
-
|
|
68
|
+
product_variant_id: Number((_item$bundle_variant_ = item === null || item === void 0 ? void 0 : item.bundle_variant_id) !== null && _item$bundle_variant_ !== void 0 ? _item$bundle_variant_ : item === null || item === void 0 ? void 0 : item.product_variant_id) || 0,
|
|
69
|
+
num: typeof (item === null || item === void 0 ? void 0 : item.num) === 'number' && !Number.isNaN(item.num) ? Math.max(1, Math.floor(item.num)) : 1,
|
|
70
|
+
option: normalizeOptions(item === null || item === void 0 ? void 0 : item.option)
|
|
64
71
|
};
|
|
65
72
|
}).sort(function (p, q) {
|
|
66
73
|
if (p.bundle_id !== q.bundle_id) return p.bundle_id - q.bundle_id;
|
|
67
74
|
if (p.product_id !== q.product_id) return p.product_id - q.product_id;
|
|
68
|
-
|
|
75
|
+
if (p.product_variant_id !== q.product_variant_id) {
|
|
76
|
+
return p.product_variant_id - q.product_variant_id;
|
|
77
|
+
}
|
|
78
|
+
if (p.num !== q.num) return p.num - q.num;
|
|
79
|
+
return JSON.stringify(p.option).localeCompare(JSON.stringify(q.option));
|
|
69
80
|
});
|
|
70
81
|
return JSON.stringify([normalizedOpts, normalizedBundles]);
|
|
71
82
|
}
|
|
@@ -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 | 2 | 1 | 6 | 4 | 3 | 5;
|
|
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);
|
|
@@ -2644,10 +2644,7 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
|
|
|
2644
2644
|
_context30.next = 11;
|
|
2645
2645
|
break;
|
|
2646
2646
|
}
|
|
2647
|
-
return _context30.abrupt("return", this.store.order.addProductsToOrder(orderLines
|
|
2648
|
-
skipEditDiscountConfigRefresh: true,
|
|
2649
|
-
skipDiscountRecalculation: true
|
|
2650
|
-
}));
|
|
2647
|
+
return _context30.abrupt("return", this.store.order.addProductsToOrder(orderLines));
|
|
2651
2648
|
case 11:
|
|
2652
2649
|
result = [];
|
|
2653
2650
|
_iterator2 = _createForOfIteratorHelper(orderLines);
|
|
@@ -118,12 +118,15 @@ export interface BookingTicketCartBookingView extends ISalesBooking {
|
|
|
118
118
|
canAddTime: boolean;
|
|
119
119
|
};
|
|
120
120
|
}
|
|
121
|
+
export type BookingTicketCartLineView = BookingTicketCartBookingView | BookingTicketCartItemView;
|
|
121
122
|
/**
|
|
122
123
|
* BookingTicket 面向 UI 的购物车视图。
|
|
123
124
|
*/
|
|
124
125
|
export interface BookingTicketCartView {
|
|
125
126
|
bookings: BookingTicketCartBookingView[];
|
|
126
127
|
items: BookingTicketCartItemView[];
|
|
128
|
+
/** 以 tempOrder.products 为唯一顺序真源的统一购物车行(旧到新)。 */
|
|
129
|
+
lines: BookingTicketCartLineView[];
|
|
127
130
|
}
|
|
128
131
|
/**
|
|
129
132
|
* BookingTicket 面向 UI 的客户展示视图。
|
|
@@ -108,33 +108,28 @@ export function buildCartView(lines, bookings) {
|
|
|
108
108
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
109
109
|
var productLines = Array.isArray(lines) ? lines : [];
|
|
110
110
|
var bookingList = Array.isArray(bookings) ? bookings : [];
|
|
111
|
+
var childBookings = bookingList.filter(function (booking) {
|
|
112
|
+
return booking.parent_id !== 0;
|
|
113
|
+
});
|
|
114
|
+
var bookingsByProductUid = indexBookingsByProductUid(childBookings);
|
|
111
115
|
var linesByUid = indexProductsByUid(productLines);
|
|
112
116
|
var addTimeLinesByBookingUid = indexAddTimeProductsByBookingUid(productLines);
|
|
113
|
-
var claimedUids = new Set();
|
|
114
117
|
var claimedAddTimeLines = new Set();
|
|
115
|
-
|
|
116
|
-
return booking.parent_id !== 0;
|
|
117
|
-
}).reduce(function (acc, booking) {
|
|
118
|
-
var uid = booking === null || booking === void 0 ? void 0 : booking.product_uid;
|
|
118
|
+
childBookings.forEach(function (booking) {
|
|
119
119
|
var bookingUid = getBookingUid(booking);
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (!claimedUids.has(key)) {
|
|
124
|
-
var line = linesByUid[key];
|
|
125
|
-
// 赠品预约只作为提交数据保留,不在购物车顶部预约卡片区展示。
|
|
126
|
-
if (isGiftProductLine(line)) return acc;
|
|
127
|
-
if (line) {
|
|
128
|
-
claimedUids.add(key);
|
|
129
|
-
product = line;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
var addTimeProduct = bookingUid ? addTimeLinesByBookingUid[bookingUid] || [] : [];
|
|
134
|
-
addTimeProduct.forEach(function (line) {
|
|
135
|
-
return claimedAddTimeLines.add(line);
|
|
120
|
+
if (!bookingUid) return;
|
|
121
|
+
(addTimeLinesByBookingUid[bookingUid] || []).forEach(function (line) {
|
|
122
|
+
claimedAddTimeLines.add(line);
|
|
136
123
|
});
|
|
137
|
-
|
|
124
|
+
});
|
|
125
|
+
var claimedBookings = new Set();
|
|
126
|
+
var cartBookings = [];
|
|
127
|
+
var items = [];
|
|
128
|
+
var orderedLines = [];
|
|
129
|
+
var buildBookingView = function buildBookingView(booking, product) {
|
|
130
|
+
var bookingUid = getBookingUid(booking);
|
|
131
|
+
var addTimeProduct = bookingUid ? addTimeLinesByBookingUid[bookingUid] || [] : [];
|
|
132
|
+
return _objectSpread(_objectSpread({}, booking), {}, {
|
|
138
133
|
_extend: {
|
|
139
134
|
product: product,
|
|
140
135
|
addTimeProduct: addTimeProduct,
|
|
@@ -147,21 +142,38 @@ export function buildCartView(lines, bookings) {
|
|
|
147
142
|
shopOpeningHours: options.shopOpeningHours
|
|
148
143
|
})
|
|
149
144
|
}
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
var items = productLines.filter(function (line) {
|
|
145
|
+
});
|
|
146
|
+
};
|
|
147
|
+
productLines.forEach(function (line) {
|
|
154
148
|
var _line$metadata6;
|
|
155
|
-
//
|
|
156
|
-
if (isGiftProductLine(line)) return
|
|
157
|
-
if (claimedAddTimeLines.has(line)) return false;
|
|
149
|
+
// 赠品由主商品 Gift 行展示;加时商品挂在 booking._extend.addTimeProduct。
|
|
150
|
+
if (isGiftProductLine(line) || claimedAddTimeLines.has(line)) return;
|
|
158
151
|
var uid = (_line$metadata6 = line.metadata) === null || _line$metadata6 === void 0 ? void 0 : _line$metadata6.unique_identification_number;
|
|
159
|
-
|
|
160
|
-
|
|
152
|
+
var matchedBooking = uid === undefined || uid === null || uid === '' ? undefined : (bookingsByProductUid[String(uid)] || []).find(function (booking) {
|
|
153
|
+
return !claimedBookings.has(booking);
|
|
154
|
+
});
|
|
155
|
+
if (matchedBooking) {
|
|
156
|
+
claimedBookings.add(matchedBooking);
|
|
157
|
+
var bookingView = buildBookingView(matchedBooking, line);
|
|
158
|
+
cartBookings.push(bookingView);
|
|
159
|
+
orderedLines.push(bookingView);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
items.push(line);
|
|
163
|
+
orderedLines.push(line);
|
|
164
|
+
});
|
|
165
|
+
childBookings.forEach(function (booking) {
|
|
166
|
+
if (claimedBookings.has(booking)) return;
|
|
167
|
+
var uid = booking === null || booking === void 0 ? void 0 : booking.product_uid;
|
|
168
|
+
var linkedProduct = uid === undefined || uid === null || uid === '' ? null : linesByUid[String(uid)] || null;
|
|
169
|
+
// 赠品预约只作为提交数据保留,不在购物车预约卡片区展示。
|
|
170
|
+
if (isGiftProductLine(linkedProduct)) return;
|
|
171
|
+
cartBookings.push(buildBookingView(booking, null));
|
|
161
172
|
});
|
|
162
173
|
return {
|
|
163
174
|
bookings: cartBookings,
|
|
164
|
-
items: items
|
|
175
|
+
items: items,
|
|
176
|
+
lines: orderedLines
|
|
165
177
|
};
|
|
166
178
|
}
|
|
167
179
|
export function isWalkInCustomer(customer) {
|
|
@@ -95,6 +95,7 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
|
|
|
95
95
|
* 2) 若无 active,返回已超时且仍占用中的预约(允许并发多条)
|
|
96
96
|
* 3) 若仍无,返回最近一组未来预约(同 start_time 的并发预约全部返回)
|
|
97
97
|
* 4) 最后兜底返回一条(避免资源有历史预约时完全无反馈)
|
|
98
|
+
* - includeAllFuture 时,保留选中预约并返回当天全部后续预约;仅详情接口启用。
|
|
98
99
|
*/
|
|
99
100
|
private pickBookingsForCurrentPoint;
|
|
100
101
|
/**
|
|
@@ -485,11 +485,13 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
485
485
|
* 2) 若无 active,返回已超时且仍占用中的预约(允许并发多条)
|
|
486
486
|
* 3) 若仍无,返回最近一组未来预约(同 start_time 的并发预约全部返回)
|
|
487
487
|
* 4) 最后兜底返回一条(避免资源有历史预约时完全无反馈)
|
|
488
|
+
* - includeAllFuture 时,保留选中预约并返回当天全部后续预约;仅详情接口启用。
|
|
488
489
|
*/
|
|
489
490
|
}, {
|
|
490
491
|
key: "pickBookingsForCurrentPoint",
|
|
491
492
|
value: function pickBookingsForCurrentPoint(current, bookings) {
|
|
492
493
|
var _this4 = this;
|
|
494
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
493
495
|
if (bookings.length === 0) return [];
|
|
494
496
|
var currentDayStart = current.startOf('day');
|
|
495
497
|
var currentDayEnd = current.endOf('day');
|
|
@@ -504,6 +506,13 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
504
506
|
if (dayScopedBookings.length === 0) return [];
|
|
505
507
|
var appendNextStartGroupIfNeeded = function appendNextStartGroupIfNeeded(selectedBookings) {
|
|
506
508
|
if (selectedBookings.length === 0) return selectedBookings;
|
|
509
|
+
if (options.includeAllFuture) {
|
|
510
|
+
var allFutureBookings = dayScopedBookings.filter(function (booking) {
|
|
511
|
+
var startAt = _this4.toBookingDateTime(booking.start_date, booking.start_time);
|
|
512
|
+
return startAt.isValid() && startAt.isAfter(current);
|
|
513
|
+
});
|
|
514
|
+
return [].concat(_toConsumableArray(selectedBookings), _toConsumableArray(allFutureBookings));
|
|
515
|
+
}
|
|
507
516
|
var shouldAppendNextGroup = selectedBookings.some(function (booking) {
|
|
508
517
|
return booking.status === 'reserved' || booking.status === 'occupied';
|
|
509
518
|
});
|
|
@@ -554,6 +563,7 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
554
563
|
return startAt.isValid() && startAt.isAfter(current) && startAt.isSame(current, 'day');
|
|
555
564
|
});
|
|
556
565
|
if (upcoming.length > 0) {
|
|
566
|
+
if (options.includeAllFuture) return upcoming;
|
|
557
567
|
var firstStartAt = this.toBookingDateTime(upcoming[0].start_date, upcoming[0].start_time).valueOf();
|
|
558
568
|
var upcomingStartGroup = upcoming.filter(function (booking) {
|
|
559
569
|
var startAt = _this4.toBookingDateTime(booking.start_date, booking.start_time);
|
|
@@ -907,7 +917,9 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
907
917
|
unpaidBookingList = matchedBookingList.filter(function (booking) {
|
|
908
918
|
return _this7.isUnpaidBooking(booking);
|
|
909
919
|
});
|
|
910
|
-
bookings = this.pickBookingsForCurrentPoint(current, this.normalizeResourceBookings(current, deviceCurrent, matchedBookingList)
|
|
920
|
+
bookings = this.pickBookingsForCurrentPoint(current, this.normalizeResourceBookings(current, deviceCurrent, matchedBookingList), {
|
|
921
|
+
includeAllFuture: true
|
|
922
|
+
});
|
|
911
923
|
completedBookings = completedBookingList.map(function (booking) {
|
|
912
924
|
return _objectSpread(_objectSpread({}, booking), {}, {
|
|
913
925
|
status: 'compelete',
|
|
@@ -919,7 +931,9 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
919
931
|
remainingReserveTime: undefined
|
|
920
932
|
});
|
|
921
933
|
});
|
|
922
|
-
unpaidBookings = this.pickBookingsForCurrentPoint(current, this.normalizeResourceBookings(current, deviceCurrent, unpaidBookingList)
|
|
934
|
+
unpaidBookings = this.pickBookingsForCurrentPoint(current, this.normalizeResourceBookings(current, deviceCurrent, unpaidBookingList), {
|
|
935
|
+
includeAllFuture: true
|
|
936
|
+
});
|
|
923
937
|
orderCount = this.countBookingOrders(statsBookingList);
|
|
924
938
|
bookingCount = statsBookingList.length;
|
|
925
939
|
compeleteBookingCount = this.countCompletedBookings(statsBookingList);
|
|
@@ -388,35 +388,46 @@ export function attachItemRuleLimitsToTopLevelProducts(productList, limits) {
|
|
|
388
388
|
* 数组元素先按主键排序再序列化,避免顺序差异导致误判为不同行。
|
|
389
389
|
*/
|
|
390
390
|
export function buildProductLineFingerprint(productOptionItem, productBundle) {
|
|
391
|
-
var
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
391
|
+
var normalizeOptions = function normalizeOptions(options) {
|
|
392
|
+
var optionArr = Array.isArray(options) ? options : [];
|
|
393
|
+
return optionArr.map(function (item) {
|
|
394
|
+
var _ref, _item$add_price;
|
|
395
|
+
return {
|
|
396
|
+
option_group_item_id: Number(item === null || item === void 0 ? void 0 : item.option_group_item_id) || 0,
|
|
397
|
+
option_group_id: Number(item === null || item === void 0 ? void 0 : item.option_group_id) || 0,
|
|
398
|
+
num: typeof (item === null || item === void 0 ? void 0 : item.num) === 'number' && !Number.isNaN(item.num) ? Math.max(1, Math.floor(item.num)) : 1,
|
|
399
|
+
price: String((_ref = (_item$add_price = item === null || item === void 0 ? void 0 : item.add_price) !== null && _item$add_price !== void 0 ? _item$add_price : item === null || item === void 0 ? void 0 : item.price) !== null && _ref !== void 0 ? _ref : '')
|
|
400
|
+
};
|
|
401
|
+
}).sort(function (p, q) {
|
|
402
|
+
if (p.option_group_item_id !== q.option_group_item_id) {
|
|
403
|
+
return p.option_group_item_id - q.option_group_item_id;
|
|
404
|
+
}
|
|
405
|
+
if (p.option_group_id !== q.option_group_id) {
|
|
406
|
+
return p.option_group_id - q.option_group_id;
|
|
407
|
+
}
|
|
408
|
+
if (p.num !== q.num) return p.num - q.num;
|
|
409
|
+
return p.price.localeCompare(q.price);
|
|
410
|
+
});
|
|
411
|
+
};
|
|
412
|
+
var normalizedOpts = normalizeOptions(productOptionItem);
|
|
408
413
|
var bundleArr = Array.isArray(productBundle) ? productBundle : [];
|
|
409
414
|
var normalizedBundles = bundleArr.map(function (item) {
|
|
410
|
-
var _ref2, _item$bundle_id;
|
|
415
|
+
var _ref2, _item$bundle_id, _item$bundle_variant_;
|
|
411
416
|
return {
|
|
412
417
|
bundle_id: Number((_ref2 = (_item$bundle_id = item === null || item === void 0 ? void 0 : item.bundle_id) !== null && _item$bundle_id !== void 0 ? _item$bundle_id : item === null || item === void 0 ? void 0 : item.id) !== null && _ref2 !== void 0 ? _ref2 : 0) || 0,
|
|
413
418
|
product_id: Number(item === null || item === void 0 ? void 0 : item.product_id) || 0,
|
|
414
|
-
|
|
419
|
+
product_variant_id: Number((_item$bundle_variant_ = item === null || item === void 0 ? void 0 : item.bundle_variant_id) !== null && _item$bundle_variant_ !== void 0 ? _item$bundle_variant_ : item === null || item === void 0 ? void 0 : item.product_variant_id) || 0,
|
|
420
|
+
num: typeof (item === null || item === void 0 ? void 0 : item.num) === 'number' && !Number.isNaN(item.num) ? Math.max(1, Math.floor(item.num)) : 1,
|
|
421
|
+
option: normalizeOptions(item === null || item === void 0 ? void 0 : item.option)
|
|
415
422
|
};
|
|
416
423
|
}).sort(function (p, q) {
|
|
417
424
|
if (p.bundle_id !== q.bundle_id) return p.bundle_id - q.bundle_id;
|
|
418
425
|
if (p.product_id !== q.product_id) return p.product_id - q.product_id;
|
|
419
|
-
|
|
426
|
+
if (p.product_variant_id !== q.product_variant_id) {
|
|
427
|
+
return p.product_variant_id - q.product_variant_id;
|
|
428
|
+
}
|
|
429
|
+
if (p.num !== q.num) return p.num - q.num;
|
|
430
|
+
return JSON.stringify(p.option).localeCompare(JSON.stringify(q.option));
|
|
420
431
|
});
|
|
421
432
|
return JSON.stringify([normalizedOpts, normalizedBundles]);
|
|
422
433
|
}
|
|
@@ -63,8 +63,24 @@ 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;
|
|
79
|
+
/**
|
|
80
|
+
* 清除当前 cacheId 的可恢复订单快照,同时保留 Solution UI sessionState。
|
|
81
|
+
* 用于支付跳转等终态场景,避免浏览器返回时恢复已提交订单。
|
|
82
|
+
*/
|
|
83
|
+
clearSessionStorageOrderSnapshot(): void;
|
|
68
84
|
/**
|
|
69
85
|
* Kiosk 不能把已收款订单留在本地等待重试:默认直接等待云端 checkout。
|
|
70
86
|
* 兼容仍需要 WebPOS 待同步模式的入口可显式传 checkoutSyncTaskEnabled: true。
|
|
@@ -111,10 +127,6 @@ export declare class UnifiedBookingSalesImpl extends BookingTicket {
|
|
|
111
127
|
* Read-only compatibility view for salesSdk skins. It reconnects a booking to its product but
|
|
112
128
|
* must not be used to mutate tempOrder; all writes go through BaseSales / planner APIs.
|
|
113
129
|
*/
|
|
114
|
-
getCart(): {
|
|
115
|
-
items: any[];
|
|
116
|
-
bookings: any[];
|
|
117
|
-
};
|
|
118
130
|
/**
|
|
119
131
|
* Loads the current customer's product coupons and discount cards after planner lines exist,
|
|
120
132
|
* then optionally lets the existing Rules engine select the best valid combination. This is a
|