@pisell/pisellos 2.2.188 → 2.2.189

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.
Files changed (34) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  2. package/dist/modules/Order/index.d.ts +1 -0
  3. package/dist/modules/Order/index.js +32 -24
  4. package/dist/modules/Order/types.d.ts +1 -0
  5. package/dist/modules/Order/utils.js +3 -1
  6. package/dist/solution/BaseSales/index.js +20 -21
  7. package/dist/solution/BookingByStep/index.d.ts +1 -1
  8. package/dist/solution/BookingTicket/index.d.ts +15 -0
  9. package/dist/solution/BookingTicket/index.js +117 -6
  10. package/dist/solution/BookingTicket/types.d.ts +48 -0
  11. package/dist/solution/BookingTicket/types.js +5 -1
  12. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +36 -0
  13. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +394 -0
  14. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +32 -0
  15. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.js +56 -0
  16. package/dist/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
  17. package/dist/solution/BookingTicket/utils/scan/scanProductValues.js +150 -0
  18. package/lib/model/strategy/adapter/promotion/index.js +49 -0
  19. package/lib/modules/Order/index.d.ts +1 -0
  20. package/lib/modules/Order/index.js +10 -5
  21. package/lib/modules/Order/types.d.ts +1 -0
  22. package/lib/modules/Order/utils.js +1 -0
  23. package/lib/solution/BaseSales/index.js +0 -1
  24. package/lib/solution/BookingByStep/index.d.ts +1 -1
  25. package/lib/solution/BookingTicket/index.d.ts +15 -0
  26. package/lib/solution/BookingTicket/index.js +56 -0
  27. package/lib/solution/BookingTicket/types.d.ts +48 -0
  28. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +36 -0
  29. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +166 -0
  30. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +32 -0
  31. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +51 -0
  32. package/lib/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
  33. package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +127 -0
  34. package/package.json +1 -1
@@ -0,0 +1,9 @@
1
+ // 导出评估器
2
+ export { PromotionEvaluator } from "./evaluator";
3
+
4
+ // 导出适配器
5
+ export { PromotionAdapter } from "./adapter";
6
+ export { default } from "./adapter";
7
+
8
+ // 导出策略配置示例常量
9
+ export { X_ITEMS_FOR_Y_PRICE_STRATEGY, BUY_X_GET_Y_FREE_STRATEGY } from "./examples";
@@ -143,6 +143,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
143
143
  private saveDraftInBackground;
144
144
  private hydrateTempOrderFromLocalRecord;
145
145
  private extractOrderIdFromSubmitResult;
146
+ private calculatePaymentEffectiveAmount;
146
147
  private calculatePaymentTotal;
147
148
  private normalizePaymentSource;
148
149
  private updateTempOrderPaymentStatus;
@@ -1121,15 +1121,21 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1121
1121
  var _ref3, _ref4, _ref5, _result$data$order_id, _result$data, _result$data2;
1122
1122
  return (_ref3 = (_ref4 = (_ref5 = (_result$data$order_id = result === null || result === void 0 || (_result$data = result.data) === null || _result$data === void 0 ? void 0 : _result$data.order_id) !== null && _result$data$order_id !== void 0 ? _result$data$order_id : result === null || result === void 0 ? void 0 : result.order_id) !== null && _ref5 !== void 0 ? _ref5 : result === null || result === void 0 || (_result$data2 = result.data) === null || _result$data2 === void 0 ? void 0 : _result$data2.id) !== null && _ref4 !== void 0 ? _ref4 : result === null || result === void 0 ? void 0 : result.id) !== null && _ref3 !== void 0 ? _ref3 : null;
1123
1123
  }
1124
+ }, {
1125
+ key: "calculatePaymentEffectiveAmount",
1126
+ value: function calculatePaymentEffectiveAmount(payment) {
1127
+ var amount = new Decimal(payment.amount || 0).minus(new Decimal(payment.service_fee || 0));
1128
+ var rounding = new Decimal(payment.rounding_amount || 0);
1129
+ return amount.minus(rounding);
1130
+ }
1124
1131
  }, {
1125
1132
  key: "calculatePaymentTotal",
1126
1133
  value: function calculatePaymentTotal(payments) {
1134
+ var _this3 = this;
1127
1135
  return mapPaymentItemsToOrderPayments(payments, {
1128
1136
  includeVoided: false
1129
1137
  }).reduce(function (sum, payment) {
1130
- var amount = new Decimal(payment.amount || 0).minus(new Decimal(payment.service_fee || 0));
1131
- var rounding = new Decimal(payment.rounding_amount || 0);
1132
- return sum.plus(amount.minus(rounding));
1138
+ return sum.plus(_this3.calculatePaymentEffectiveAmount(payment));
1133
1139
  }, new Decimal(0));
1134
1140
  }
1135
1141
  }, {
@@ -1170,18 +1176,20 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1170
1176
  }, {
1171
1177
  key: "calculatePaidPaymentSummary",
1172
1178
  value: function calculatePaidPaymentSummary(payments) {
1173
- var _this3 = this;
1179
+ var _this4 = this;
1174
1180
  return (payments || []).reduce(function (summary, payment) {
1175
1181
  var paymentRecord = payment;
1176
1182
  if ((paymentRecord === null || paymentRecord === void 0 ? void 0 : paymentRecord.status) !== 'paid') return summary;
1177
1183
  return {
1178
1184
  customerPaidAmount: summary.customerPaidAmount.plus(paymentRecord.amount || 0),
1179
1185
  orderPaidAmount: summary.orderPaidAmount.plus(paymentRecord.origin_amount || 0),
1180
- payServiceChargeAmount: summary.payServiceChargeAmount.plus(_this3.calculatePaymentServiceFee(paymentRecord))
1186
+ gapPaidAmount: summary.gapPaidAmount.plus(_this4.calculatePaymentEffectiveAmount(paymentRecord)),
1187
+ payServiceChargeAmount: summary.payServiceChargeAmount.plus(_this4.calculatePaymentServiceFee(paymentRecord))
1181
1188
  };
1182
1189
  }, {
1183
1190
  customerPaidAmount: new Decimal(0),
1184
1191
  orderPaidAmount: new Decimal(0),
1192
+ gapPaidAmount: new Decimal(0),
1185
1193
  payServiceChargeAmount: new Decimal(0)
1186
1194
  });
1187
1195
  }
@@ -1565,9 +1573,9 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1565
1573
  }, {
1566
1574
  key: "findBookingIndexByUniqueIdentificationNumber",
1567
1575
  value: function findBookingIndexByUniqueIdentificationNumber(tempOrder, uniqueIdentificationNumber) {
1568
- var _this4 = this;
1576
+ var _this5 = this;
1569
1577
  return (tempOrder.bookings || []).findIndex(function (booking) {
1570
- return _this4.getBookingUniqueIdentificationNumber(booking) === uniqueIdentificationNumber;
1578
+ return _this5.getBookingUniqueIdentificationNumber(booking) === uniqueIdentificationNumber;
1571
1579
  });
1572
1580
  }
1573
1581
  }, {
@@ -1575,12 +1583,12 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1575
1583
  value: function removeLinkedBookingsForProduct(tempOrder, product) {
1576
1584
  var _product$metadata4,
1577
1585
  _product$metadata5,
1578
- _this5 = this;
1586
+ _this6 = this;
1579
1587
  var productUid = (product === null || product === void 0 || (_product$metadata4 = product.metadata) === null || _product$metadata4 === void 0 ? void 0 : _product$metadata4.unique_identification_number) || (product === null || product === void 0 ? void 0 : product.unique_identification_number);
1580
1588
  var bookingUid = (product === null || product === void 0 ? void 0 : product.booking_uid) || (product === null || product === void 0 || (_product$metadata5 = product.metadata) === null || _product$metadata5 === void 0 ? void 0 : _product$metadata5.booking_uid);
1581
1589
  if (!productUid && !bookingUid) return;
1582
1590
  tempOrder.bookings = (tempOrder.bookings || []).filter(function (booking) {
1583
- var currentBookingUid = _this5.getBookingUniqueIdentificationNumber(booking);
1591
+ var currentBookingUid = _this6.getBookingUniqueIdentificationNumber(booking);
1584
1592
  if (bookingUid && currentBookingUid === String(bookingUid)) return false;
1585
1593
  if (productUid && String((booking === null || booking === void 0 ? void 0 : booking.product_uid) || '') === String(productUid)) return false;
1586
1594
  return true;
@@ -1623,7 +1631,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1623
1631
  amount_gap: this.calculateSummaryAmountGap({
1624
1632
  tempOrder: tempOrder,
1625
1633
  summary: createEmptySummary(),
1626
- orderPaidAmount: paidPaymentSummary.orderPaidAmount
1634
+ orderPaidAmount: paidPaymentSummary.gapPaidAmount
1627
1635
  }),
1628
1636
  pay_service_charge_amount: paidPaymentSummary.payServiceChargeAmount.toFixed(2)
1629
1637
  });
@@ -1647,7 +1655,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1647
1655
  amount_gap: this.calculateSummaryAmountGap({
1648
1656
  tempOrder: tempOrder,
1649
1657
  summary: salesSummaryResult,
1650
- orderPaidAmount: paidPaymentSummary.orderPaidAmount
1658
+ orderPaidAmount: paidPaymentSummary.gapPaidAmount
1651
1659
  }),
1652
1660
  pay_service_charge_amount: paidPaymentSummary.payServiceChargeAmount.toFixed(2)
1653
1661
  });
@@ -1952,7 +1960,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1952
1960
  }, {
1953
1961
  key: "addOrderPayment",
1954
1962
  value: function addOrderPayment(payment) {
1955
- var _this6 = this;
1963
+ var _this7 = this;
1956
1964
  this.logInfo('addOrderPayment', {
1957
1965
  payment: payment
1958
1966
  });
@@ -1965,7 +1973,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1965
1973
  void this.recalculateSummary({
1966
1974
  createIfMissing: true
1967
1975
  }).catch(function (error) {
1968
- _this6.logError('recalculate summary after addOrderPayment failed', {
1976
+ _this7.logError('recalculate summary after addOrderPayment failed', {
1969
1977
  error: error instanceof Error ? error.message : String(error)
1970
1978
  });
1971
1979
  });
@@ -2030,10 +2038,10 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2030
2038
  }, {
2031
2039
  key: "updateVoucherOrderPayments",
2032
2040
  value: function updateVoucherOrderPayments(payments) {
2033
- var _this7 = this;
2041
+ var _this8 = this;
2034
2042
  var tempOrder = this.ensureTempOrder();
2035
2043
  var mappedVouchers = mapPaymentItemsToOrderPayments(payments.map(function (payment) {
2036
- return _this7.normalizePaymentSource(payment, {
2044
+ return _this8.normalizePaymentSource(payment, {
2037
2045
  defaultPaid: false
2038
2046
  });
2039
2047
  })).filter(function (payment) {
@@ -2048,7 +2056,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2048
2056
  void this.recalculateSummary({
2049
2057
  createIfMissing: true
2050
2058
  }).catch(function (error) {
2051
- _this7.logError('recalculate summary after updateVoucherOrderPayments failed', {
2059
+ _this8.logError('recalculate summary after updateVoucherOrderPayments failed', {
2052
2060
  error: error instanceof Error ? error.message : String(error)
2053
2061
  });
2054
2062
  });
@@ -2104,7 +2112,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2104
2112
  key: "addProductToOrder",
2105
2113
  value: function () {
2106
2114
  var _addProductToOrder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee16(product, booking) {
2107
- var _this8 = this;
2115
+ var _this9 = this;
2108
2116
  var tempOrder, linked, productToAdd, incomingFingerprint, normalizedIncoming, hasIncomingGoodPass, shouldForceNewLine, matchedIndex, matchedProduct, existedFingerprint, shouldMerge, _targetProduct$metada, targetProduct, targetUid, normalizedProduct;
2109
2117
  return _regeneratorRuntime().wrap(function _callee16$(_context18) {
2110
2118
  while (1) switch (_context18.prev = _context18.next) {
@@ -2122,7 +2130,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2122
2130
  hasIncomingGoodPass = this.hasGoodPassDiscount(normalizedIncoming);
2123
2131
  shouldForceNewLine = !!booking;
2124
2132
  matchedIndex = hasIncomingGoodPass || shouldForceNewLine ? -1 : tempOrder.products.findIndex(function (item) {
2125
- if (_this8.hasGoodPassDiscount(item)) return false;
2133
+ if (_this9.hasGoodPassDiscount(item)) return false;
2126
2134
  if (item.product_id !== productToAdd.product_id) return false;
2127
2135
  if (item.product_variant_id !== productToAdd.product_variant_id) return false;
2128
2136
  var existedFingerprint = buildProductLineFingerprint(item.product_option_item, item.product_bundle);
@@ -2699,10 +2707,10 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2699
2707
  value: function extractSubmitErrorResponse(error) {
2700
2708
  var _error$response,
2701
2709
  _error$response2,
2702
- _this9 = this;
2710
+ _this10 = this;
2703
2711
  var candidates = [error === null || error === void 0 || (_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.data, error === null || error === void 0 ? void 0 : error.data, error === null || error === void 0 || (_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.body, error === null || error === void 0 ? void 0 : error.body];
2704
2712
  return candidates.find(function (candidate) {
2705
- return _this9.isSubmitErrorResponse(candidate);
2713
+ return _this10.isSubmitErrorResponse(candidate);
2706
2714
  }) || null;
2707
2715
  }
2708
2716
  }, {
@@ -3280,7 +3288,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3280
3288
  }, {
3281
3289
  key: "normalizeTempOrderForRuntime",
3282
3290
  value: function normalizeTempOrderForRuntime(raw, options) {
3283
- var _this10 = this;
3291
+ var _this11 = this;
3284
3292
  var nextTempOrder = _objectSpread(_objectSpread({}, this.createDefaultTempOrderInstance()), raw || {});
3285
3293
  delete nextTempOrder.summary;
3286
3294
  delete nextTempOrder.lastOrderInfo;
@@ -3299,7 +3307,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3299
3307
  nextTempOrder.holder = raw.holder && _typeof(raw.holder) === 'object' ? _objectSpread({}, raw.holder) : null;
3300
3308
  var rawProducts = Array.isArray(raw.products) ? raw.products : [];
3301
3309
  nextTempOrder.products = rawProducts.length > 0 ? rawProducts.map(function (p) {
3302
- return _this10.normalizeHydratedOrderProduct(p);
3310
+ return _this11.normalizeHydratedOrderProduct(p);
3303
3311
  }) : [];
3304
3312
  nextTempOrder.bookings = Array.isArray(raw.bookings) ? raw.bookings.map(function (b) {
3305
3313
  return _objectSpread(_objectSpread({}, b || {}), {}, {
@@ -3459,14 +3467,14 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3459
3467
  key: "resolveHydratedProductOptions",
3460
3468
  value: function resolveHydratedProductOptions(row) {
3461
3469
  var _row$product_sku,
3462
- _this11 = this;
3470
+ _this12 = this;
3463
3471
  var skuOptions = (_row$product_sku = row.product_sku) === null || _row$product_sku === void 0 ? void 0 : _row$product_sku.option;
3464
3472
  if (Array.isArray(row.product_option_item) && row.product_option_item.length > 0) {
3465
3473
  return this.mergeHydratedProductOptionDisplayFields(row.product_option_item, skuOptions);
3466
3474
  }
3467
3475
  if (!Array.isArray(skuOptions)) return [];
3468
3476
  return skuOptions.map(function (optionItem) {
3469
- return _this11.normalizeHydratedProductOptionItem(optionItem || {});
3477
+ return _this12.normalizeHydratedProductOptionItem(optionItem || {});
3470
3478
  });
3471
3479
  }
3472
3480
  }, {
@@ -439,6 +439,7 @@ export interface OrderPaymentMetadata {
439
439
  [key: string]: any;
440
440
  }
441
441
  export interface OrderPaymentData {
442
+ order_payment_id?: number | string;
442
443
  amount: string;
443
444
  code: string;
444
445
  custom_payment_id: number;
@@ -825,7 +825,9 @@ export function mapPaymentItemToOrderPayment(paymentItem) {
825
825
  metadata[key] = item[key];
826
826
  }
827
827
  }
828
- return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
828
+ return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, item.order_payment_id !== undefined ? {
829
+ order_payment_id: item.order_payment_id
830
+ } : {}), {}, {
829
831
  amount: String((_item$amount = item.amount) !== null && _item$amount !== void 0 ? _item$amount : '0.00'),
830
832
  code: String(item.code || ''),
831
833
  custom_payment_id: Number(customPaymentId !== null && customPaymentId !== void 0 ? customPaymentId : 0),
@@ -607,7 +607,7 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
607
607
  };
608
608
  externalSaleNumber = params.externalSaleNumber || params.external_sale_number;
609
609
  if (params.forceRemote) {
610
- _context5.next = 36;
610
+ _context5.next = 35;
611
611
  break;
612
612
  }
613
613
  if (!(params.orderId !== undefined)) {
@@ -650,59 +650,58 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
650
650
  _context5.t0 = _context5.t1;
651
651
  case 26:
652
652
  localRecord = _context5.t0;
653
- debugger;
654
653
  if (!localRecord) {
655
- _context5.next = 36;
654
+ _context5.next = 35;
656
655
  break;
657
656
  }
658
- _context5.next = 31;
657
+ _context5.next = 30;
659
658
  return this.store.order.hydrateTempOrderFromRecord(localRecord, {
660
659
  recalcOnHydrate: false
661
660
  });
662
- case 31:
661
+ case 30:
663
662
  _sales = _context5.sent;
664
663
  this.currentSalesDetail = _sales;
665
- _context5.next = 35;
664
+ _context5.next = 34;
666
665
  return this.core.effects.emit("".concat(this.name, ":onSalesOrderLoaded"), {
667
666
  sales: _sales
668
667
  });
669
- case 35:
668
+ case 34:
670
669
  return _context5.abrupt("return", _sales);
671
- case 36:
670
+ case 35:
672
671
  if (!(params.orderId === undefined || params.orderId === null)) {
673
- _context5.next = 38;
672
+ _context5.next = 37;
674
673
  break;
675
674
  }
676
675
  throw new Error('加载销售详情需要 orderId,或本地库中存在对应 externalSaleNumber/orderNumber');
677
- case 38:
678
- _context5.next = 40;
676
+ case 37:
677
+ _context5.next = 39;
679
678
  return this.store.order.getOrderInfoByRemote(Number(params.orderId));
680
- case 40:
679
+ case 39:
681
680
  res = _context5.sent;
682
681
  if (!(!res || res.code !== 200)) {
683
- _context5.next = 44;
682
+ _context5.next = 43;
684
683
  break;
685
684
  }
686
685
  message = res && (res.message || res.msg) || "\u52A0\u8F7D\u9500\u552E\u8BE6\u60C5\u5931\u8D25: ".concat(params.orderId);
687
686
  throw new Error(message);
688
- case 44:
689
- _context5.next = 46;
687
+ case 43:
688
+ _context5.next = 45;
690
689
  return this.store.order.hydrateTempOrderFromRecord(res.data, {
691
690
  recalcOnHydrate: false
692
691
  });
693
- case 46:
692
+ case 45:
694
693
  sales = _context5.sent;
695
- _context5.next = 49;
694
+ _context5.next = 48;
696
695
  return this.store.order.saveDraft();
697
- case 49:
696
+ case 48:
698
697
  this.currentSalesDetail = sales;
699
- _context5.next = 52;
698
+ _context5.next = 51;
700
699
  return this.core.effects.emit("".concat(this.name, ":onSalesOrderLoaded"), {
701
700
  sales: sales
702
701
  });
703
- case 52:
702
+ case 51:
704
703
  return _context5.abrupt("return", sales);
705
- case 53:
704
+ case 52:
706
705
  case "end":
707
706
  return _context5.stop();
708
707
  }
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 1 | 2 | 3 | 5 | 4 | 6;
314
+ weekNum: 0 | 1 | 2 | 6 | 3 | 5 | 4;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -7,6 +7,7 @@ import { BaseSalesImpl } from '../BaseSales';
7
7
  import type { BaseSalesScanCodeResult } from '../BaseSales/types';
8
8
  import type { ISalesDetail } from '../BaseSales/utils/parseSalesResponse';
9
9
  import type { LoadSalesDetailParams } from '../../modules/Order/types';
10
+ import type { GlobalScanHandleResult, GlobalScanHostBridge } from './types';
10
11
  import { AddProductDecideContext, AddProductRequiresDetailPayload } from './utils/addProductDecision';
11
12
  import { type BuildCacheItemFromOrderLineInput } from '../../modules/BookingContext/utils/buildCacheItemFromOrderLine';
12
13
  import { type BuildNormalProductCacheItemFromOrderLineInput } from '../../modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine';
@@ -441,6 +442,20 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
441
442
  buildNormalProductCacheItemFromOrderLine(input: BuildNormalProductCacheItemFromOrderLineInput): Record<string, any>;
442
443
  /** 文档别名:与 OrderModule.updateOrderProduct 一致。 */
443
444
  updateProductInOrder(params: UpdateOrderProductParams): Promise<OrderProduct[]>;
445
+ /**
446
+ * 全局扫码 pubsub 入口:解析码值 → 搜索 → 业务分发(客户 / 加车 / 开单)。
447
+ * UI 层在 pubsub 订阅回调里注入 `bridge`(uiHosts / action / cart.confirm*)。
448
+ *
449
+ * @example
450
+ * ```ts
451
+ * await bookingTicket.handleGlobalScanCode(payload.data, {
452
+ * openProductDetail: uiHosts.openProductDetail,
453
+ * confirmDetail: cart.confirmDetail,
454
+ * openOrder: ({ order_id }) => action({ type: 'pisell1.handleOpenCachedBigSale', data: { order_id } }),
455
+ * });
456
+ * ```
457
+ */
458
+ handleGlobalScanCode(code: string, bridge?: GlobalScanHostBridge): Promise<GlobalScanHandleResult>;
444
459
  /**
445
460
  * 销毁模块:先调用父类(销毁所有 store 内子模块 + emit destroy + super.destroy()),
446
461
  * 再清理 BookingTicket 自有资源(scan 监听 + scan 内存缓存)。
@@ -37,6 +37,8 @@ import Scan from "./utils/scan";
37
37
  import { formatOrderCustomerPatch } from "./utils/orderCustomer";
38
38
  import { handleGlobalScan, handleCustomerScan, handleUniversalScan } from "./utils/scan/handleScan";
39
39
  import scanCache from "./utils/scan/scanCache";
40
+ import { formatGlobalScanResult } from "./utils/scan/formatGlobalScan";
41
+ import { applyGlobalScan } from "./utils/scan/applyGlobalScan";
40
42
  import { buildCartView } from "./utils/cartView";
41
43
  import { buildCacheItemFromCartDetail, buildCacheItemFromDetail, buildRequiresDetailPayload as _buildRequiresDetailPayload, decideAddProduct as decideAddProductUtil, decideAfterDetail as decideAfterDetailUtil, decideAutoClose as decideAutoCloseUtil, getIsEject as getIsEjectUtil, getIsOnlySession as getIsOnlySessionUtil, transformDetailToProductAndBooking as transformDetailToProductAndBookingUtil } from "./utils/addProductDecision";
42
44
  import { buildCacheItemFromOrderLine as buildCacheItemFromOrderLineUtil } from "../../modules/BookingContext/utils/buildCacheItemFromOrderLine";
@@ -1738,6 +1740,115 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
1738
1740
  }
1739
1741
  return updateProductInOrder;
1740
1742
  }()
1743
+ /**
1744
+ * 全局扫码 pubsub 入口:解析码值 → 搜索 → 业务分发(客户 / 加车 / 开单)。
1745
+ * UI 层在 pubsub 订阅回调里注入 `bridge`(uiHosts / action / cart.confirm*)。
1746
+ *
1747
+ * @example
1748
+ * ```ts
1749
+ * await bookingTicket.handleGlobalScanCode(payload.data, {
1750
+ * openProductDetail: uiHosts.openProductDetail,
1751
+ * confirmDetail: cart.confirmDetail,
1752
+ * openOrder: ({ order_id }) => action({ type: 'pisell1.handleOpenCachedBigSale', data: { order_id } }),
1753
+ * });
1754
+ * ```
1755
+ */
1756
+ )
1757
+ }, {
1758
+ key: "handleGlobalScanCode",
1759
+ value: (function () {
1760
+ var _handleGlobalScanCode = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee23(code, bridge) {
1761
+ var _this6 = this;
1762
+ var trimmed, _bridge$onNotify, _bridge$refresh, localSearch, scanCallback, raw, formatted, _bridge$onNotify2, _result7, _bridge$onNotify3;
1763
+ return _regeneratorRuntime().wrap(function _callee23$(_context23) {
1764
+ while (1) switch (_context23.prev = _context23.next) {
1765
+ case 0:
1766
+ trimmed = typeof code === 'string' ? code.trim() : '';
1767
+ if (trimmed) {
1768
+ _context23.next = 4;
1769
+ break;
1770
+ }
1771
+ bridge === null || bridge === void 0 || (_bridge$onNotify = bridge.onNotify) === null || _bridge$onNotify === void 0 || _bridge$onNotify.call(bridge, 'fail', 'pisell2.text.scan-global-failed');
1772
+ return _context23.abrupt("return", {
1773
+ status: 'failed',
1774
+ reason: 'empty_code'
1775
+ });
1776
+ case 4:
1777
+ _context23.prev = 4;
1778
+ localSearch = function localSearch(v) {
1779
+ return _this6.store.products.findProductsByCodeOrBarcode(v);
1780
+ };
1781
+ scanCallback = handleGlobalScan(this.request, localSearch);
1782
+ _context23.next = 9;
1783
+ return scanCallback({
1784
+ type: 'nativeScanner',
1785
+ value: trimmed
1786
+ });
1787
+ case 9:
1788
+ raw = _context23.sent;
1789
+ formatted = formatGlobalScanResult(raw, trimmed);
1790
+ if (formatted) {
1791
+ _context23.next = 14;
1792
+ break;
1793
+ }
1794
+ bridge === null || bridge === void 0 || (_bridge$onNotify2 = bridge.onNotify) === null || _bridge$onNotify2 === void 0 || _bridge$onNotify2.call(bridge, 'fail', 'pisell2.text.scan-global-failed');
1795
+ return _context23.abrupt("return", {
1796
+ status: 'failed',
1797
+ reason: 'not_found'
1798
+ });
1799
+ case 14:
1800
+ _context23.next = 16;
1801
+ return applyGlobalScan({
1802
+ setOrderCustomer: function setOrderCustomer(customer) {
1803
+ return _this6.setOrderCustomer(customer);
1804
+ },
1805
+ getOrderCustomerSnapshot: function getOrderCustomerSnapshot() {
1806
+ return _this6.getOrderCustomerSnapshot();
1807
+ },
1808
+ getBusinessCode: function getBusinessCode() {
1809
+ var _this6$otherParams;
1810
+ return (_this6$otherParams = _this6.otherParams) === null || _this6$otherParams === void 0 ? void 0 : _this6$otherParams.businessCode;
1811
+ },
1812
+ buildAddProductCtx: function buildAddProductCtx(extra) {
1813
+ return _this6.buildAddProductCtx(extra);
1814
+ },
1815
+ decideAddProduct: function decideAddProduct(item, options) {
1816
+ return _this6.decideAddProduct(item, options);
1817
+ },
1818
+ decideAfterDetail: function decideAfterDetail(cacheItem, options) {
1819
+ return _this6.decideAfterDetail(cacheItem, options);
1820
+ },
1821
+ transformDetailToProductAndBooking: function transformDetailToProductAndBooking(input) {
1822
+ return _this6.transformDetailToProductAndBooking(input);
1823
+ },
1824
+ addProductToOrder: function addProductToOrder(product, booking) {
1825
+ return _this6.addProductToOrder(product, booking);
1826
+ }
1827
+ }, formatted, bridge);
1828
+ case 16:
1829
+ _result7 = _context23.sent;
1830
+ bridge === null || bridge === void 0 || (_bridge$refresh = bridge.refresh) === null || _bridge$refresh === void 0 || _bridge$refresh.call(bridge);
1831
+ return _context23.abrupt("return", _result7);
1832
+ case 21:
1833
+ _context23.prev = 21;
1834
+ _context23.t0 = _context23["catch"](4);
1835
+ console.error('[BookingTicket] handleGlobalScanCode failed', _context23.t0);
1836
+ bridge === null || bridge === void 0 || (_bridge$onNotify3 = bridge.onNotify) === null || _bridge$onNotify3 === void 0 || _bridge$onNotify3.call(bridge, 'fail', 'pisell2.text.scan-global-failed');
1837
+ return _context23.abrupt("return", {
1838
+ status: 'failed',
1839
+ reason: 'not_found'
1840
+ });
1841
+ case 26:
1842
+ case "end":
1843
+ return _context23.stop();
1844
+ }
1845
+ }, _callee23, this, [[4, 21]]);
1846
+ }));
1847
+ function handleGlobalScanCode(_x18, _x19) {
1848
+ return _handleGlobalScanCode.apply(this, arguments);
1849
+ }
1850
+ return handleGlobalScanCode;
1851
+ }()
1741
1852
  /**
1742
1853
  * 销毁模块:先调用父类(销毁所有 store 内子模块 + emit destroy + super.destroy()),
1743
1854
  * 再清理 BookingTicket 自有资源(scan 监听 + scan 内存缓存)。
@@ -1746,12 +1857,12 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
1746
1857
  }, {
1747
1858
  key: "destroy",
1748
1859
  value: (function () {
1749
- var _destroy = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee23() {
1860
+ var _destroy = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee24() {
1750
1861
  var _this$scan;
1751
- return _regeneratorRuntime().wrap(function _callee23$(_context23) {
1752
- while (1) switch (_context23.prev = _context23.next) {
1862
+ return _regeneratorRuntime().wrap(function _callee24$(_context24) {
1863
+ while (1) switch (_context24.prev = _context24.next) {
1753
1864
  case 0:
1754
- _context23.next = 2;
1865
+ _context24.next = 2;
1755
1866
  return _get(_getPrototypeOf(BookingTicketImpl.prototype), "destroy", this).call(this);
1756
1867
  case 2:
1757
1868
  try {
@@ -1762,9 +1873,9 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
1762
1873
  scanCache.clear();
1763
1874
  case 4:
1764
1875
  case "end":
1765
- return _context23.stop();
1876
+ return _context24.stop();
1766
1877
  }
1767
- }, _callee23, this);
1878
+ }, _callee24, this);
1768
1879
  }));
1769
1880
  function destroy() {
1770
1881
  return _destroy.apply(this, arguments);
@@ -134,3 +134,51 @@ export interface BookingTicketCustomerView {
134
134
  export interface BookingTicketProductCatalogView {
135
135
  products: ProductData[];
136
136
  }
137
+ /** 扫码宿主桥接:SalesSdk 在 pubsub 订阅回调里注入,OS 需要 UI 时直接调用 */
138
+ export interface GlobalScanHostBridge {
139
+ openProductDetail?: (payload: Record<string, any>) => Promise<any | null>;
140
+ openBookingEdit?: (payload: Record<string, any>) => Promise<any | null>;
141
+ confirmDetail?: (input: {
142
+ item: any;
143
+ detailResult: {
144
+ e: any;
145
+ extension_type?: any;
146
+ detail?: any;
147
+ };
148
+ options?: Record<string, any>;
149
+ }) => Promise<any>;
150
+ confirmBookingEdit?: (input: {
151
+ cacheItem: any;
152
+ options?: Record<string, any>;
153
+ }) => Promise<any>;
154
+ openOrder?: (data: {
155
+ order_id: number;
156
+ business_code?: string;
157
+ }) => void;
158
+ /**
159
+ * walk-in 扫 walletPass:直接核销优惠码(对齐 SaleDetail Voucher.handleApplyCode / cart.scanCode)。
160
+ */
161
+ applyPromotionCode?: (code: string, customerId?: number) => Promise<{
162
+ isAvailable?: boolean;
163
+ type?: string;
164
+ unavailableReason?: string;
165
+ }>;
166
+ onNotify?: (type: 'success' | 'fail' | 'info', messageKey?: string) => void;
167
+ refresh?: () => void;
168
+ }
169
+ /** handleGlobalScanCode 结构化返回 */
170
+ export type GlobalScanHandleResult = {
171
+ status: 'success';
172
+ kind: 'customer' | 'products' | 'promotion';
173
+ meta?: {
174
+ count?: number;
175
+ };
176
+ } | {
177
+ status: 'pending';
178
+ kind: 'openOrder' | 'requiresDetail' | 'requiresBookingEdit';
179
+ } | {
180
+ status: 'cancelled';
181
+ } | {
182
+ status: 'failed';
183
+ reason: 'empty_code' | 'not_found' | 'invalid_data' | 'no_bridge';
184
+ };
@@ -77,4 +77,8 @@ export var BookingTicketHooks = /*#__PURE__*/function (BookingTicketHooks) {
77
77
 
78
78
  /**
79
79
  * BookingTicket 当前已加载的商品池视图。
80
- */
80
+ */
81
+
82
+ /** 扫码宿主桥接:SalesSdk 在 pubsub 订阅回调里注入,OS 需要 UI 时直接调用 */
83
+
84
+ /** handleGlobalScanCode 结构化返回 */
@@ -0,0 +1,36 @@
1
+ import type { GlobalScanHandleResult, GlobalScanHostBridge, ICustomer } from '../../types';
2
+ import type { AddProductDecision } from '../addProductDecision';
3
+ import { GlobalScanFormattedResult } from './formatGlobalScan';
4
+ /** applyGlobalScan 所需的 BookingTicket 运行时能力 */
5
+ export interface GlobalScanApplyHost {
6
+ setOrderCustomer(customer: ICustomer | null): void;
7
+ getOrderCustomerSnapshot(): ICustomer | null;
8
+ getBusinessCode(): string | undefined;
9
+ buildAddProductCtx(extra?: Record<string, any>): Record<string, any>;
10
+ decideAddProduct(item: any, options?: Record<string, any>): AddProductDecision;
11
+ decideAfterDetail(cacheItem: any, options?: Record<string, any>): AddProductDecision;
12
+ transformDetailToProductAndBooking(input: {
13
+ item: any;
14
+ cacheItem?: any;
15
+ detailResult?: {
16
+ e: any;
17
+ extension_type?: any;
18
+ detail?: any;
19
+ };
20
+ options?: Record<string, any>;
21
+ }): {
22
+ product: any;
23
+ booking?: any;
24
+ cacheItem: any;
25
+ };
26
+ addProductToOrder(product: any, booking?: any): Promise<any>;
27
+ }
28
+ /**
29
+ * 应用全局扫码格式化结果:设客户 / 加车 / 开单 / 弹窗链。
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const result = await applyGlobalScan(bookingTicket, formatted, bridge);
34
+ * ```
35
+ */
36
+ export declare function applyGlobalScan(host: GlobalScanApplyHost, formatted: GlobalScanFormattedResult, bridge?: GlobalScanHostBridge): Promise<GlobalScanHandleResult>;