@pisell/pisellos 2.2.281 → 2.2.283

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.
@@ -45,6 +45,7 @@ var PisellOSCore = /*#__PURE__*/function () {
45
45
  this.serverOptions = options.server;
46
46
  }
47
47
  this.initialize(options);
48
+ console.log('constructor123456543');
48
49
  }
49
50
  _createClass(PisellOSCore, [{
50
51
  key: "initialize",
@@ -512,7 +512,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
512
512
  generateIdempotencyToken(): string;
513
513
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
514
514
  createOrder(params: CommitOrderParams['query']): {
515
- type: "virtual" | "appointment_booking";
515
+ type: "appointment_booking" | "virtual";
516
516
  platform: string;
517
517
  sales_channel: string;
518
518
  order_sales_channel: string;
@@ -37,7 +37,7 @@ import { isNormalProduct } from "../Product/utils";
37
37
  import dayjs from 'dayjs';
38
38
  import { ensureOrderPaymentNumber, mergeOrderPaymentRecord, resolveOrderPaymentIdentity } from "./payment-utils";
39
39
  import { resolvePaymentNumberDevicePrefix, resolvePaymentNumberDevicePrefixFromDeviceId } from "../../utils/payment-number";
40
- import { processCartPromotion, appendPromotionTags as _appendPromotionTags, getOrderProductUid as getPromotionUid } from "../../solution/BaseSales/utils/cartPromotion";
40
+ import { processCartPromotion, appendPromotionTags as _appendPromotionTags, getOrderProductUid as getPromotionUid, PRODUCT_LINE_MERGE_DISABLED_METADATA_KEY } from "../../solution/BaseSales/utils/cartPromotion";
41
41
  import { buildProductLineFingerprint, getProductIdentityIndex, getSafeProductNum, isIdentityMatch, normalizeOrderProduct } from "../../solution/ScanOrder/utils";
42
42
  import { hasManualProductDiscountFlag, syncManualProductDiscountProductNum } from "./utils/manualProductDiscount";
43
43
  import { expandHydratedProductsForDiscountCollection, restoreHydratedBundleDiscounts } from "./utils/bundleDiscountHydration";
@@ -4018,8 +4018,12 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
4018
4018
  booking: booking
4019
4019
  }) : null;
4020
4020
  var productToAdd = (linked === null || linked === void 0 ? void 0 : linked.product) || product;
4021
- var incomingFingerprint = buildProductLineFingerprint(getProductSkuOptions(productToAdd), productToAdd.product_bundle);
4021
+ var disableMerge = (options === null || options === void 0 ? void 0 : options.disableMerge) === true;
4022
+ var incomingFingerprint = disableMerge ? '' : buildProductLineFingerprint(getProductSkuOptions(productToAdd), productToAdd.product_bundle);
4022
4023
  var normalizedIncoming = mergeOrderProductDisplayFields(productToAdd, normalizeOrderProduct(productToAdd));
4024
+ if (disableMerge) {
4025
+ normalizedIncoming.metadata = _objectSpread(_objectSpread({}, normalizedIncoming.metadata || {}), {}, _defineProperty({}, PRODUCT_LINE_MERGE_DISABLED_METADATA_KEY, true));
4026
+ }
4023
4027
  var isWeighingProduct = Number(((_normalizedIncoming$p = normalizedIncoming.product_sku) === null || _normalizedIncoming$p === void 0 ? void 0 : _normalizedIncoming$p.open_sold_weight) || 0) === 1;
4024
4028
  var netWeight = Number((_normalizedIncoming$p2 = normalizedIncoming.product_sku) === null || _normalizedIncoming$p2 === void 0 ? void 0 : _normalizedIncoming$p2.net_weight);
4025
4029
  if (isWeighingProduct && (!Number.isFinite(netWeight) || netWeight <= 0)) {
@@ -4038,7 +4042,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
4038
4042
  var hasIncomingManualProductDiscount = isManualProductDiscountProduct(normalizedIncoming);
4039
4043
  var hasIncomingBookingUid = this.hasLinkedBookingUid(productToAdd) || this.hasLinkedBookingUid(normalizedIncoming);
4040
4044
  var isIncomingCustomItem = ((_productToAdd$metadat = productToAdd.metadata) === null || _productToAdd$metadat === void 0 || (_productToAdd$metadat = _productToAdd$metadat.origin) === null || _productToAdd$metadat === void 0 ? void 0 : _productToAdd$metadat.isCustomItem) === true || ((_origin = productToAdd._origin) === null || _origin === void 0 ? void 0 : _origin.isCustomItem) === true;
4041
- var shouldForceNewLine = !!booking || hasIncomingProductNote || hasIncomingManualProductDiscount || hasIncomingBookingUid || isIncomingCustomItem || isWeighingProduct;
4045
+ var shouldForceNewLine = disableMerge || !!booking || hasIncomingProductNote || hasIncomingManualProductDiscount || hasIncomingBookingUid || isIncomingCustomItem || isWeighingProduct;
4042
4046
  var matchedIndex = hasIncomingGoodPass || shouldForceNewLine ? -1 : tempOrder.products.findIndex(function (item) {
4043
4047
  var _item$metadata3;
4044
4048
  if (_this27.hasGoodPassDiscount(item)) return false;
@@ -4168,7 +4172,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
4168
4172
  singleLine.num = 1;
4169
4173
  delete singleLine.product_quantity;
4170
4174
  _appendResult = this.appendProductLineToTempOrder(tempOrder, singleLine, cloneDeep(booking), {
4171
- insertAtIndex: insertAtIndex
4175
+ insertAtIndex: insertAtIndex,
4176
+ disableMerge: options === null || options === void 0 ? void 0 : options.disableMerge
4172
4177
  });
4173
4178
  if (!_appendResult) {
4174
4179
  _context21.next = 17;
@@ -4189,7 +4194,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
4189
4194
  return _context21.abrupt("return", tempOrder.products);
4190
4195
  case 24:
4191
4196
  appendResult = this.appendProductLineToTempOrder(tempOrder, product, booking, {
4192
- insertAtIndex: insertAtIndex
4197
+ insertAtIndex: insertAtIndex,
4198
+ disableMerge: options === null || options === void 0 ? void 0 : options.disableMerge
4193
4199
  });
4194
4200
  if (!appendResult) {
4195
4201
  _context21.next = 28;
@@ -157,13 +157,11 @@ export interface OrderCustomerPatch {
157
157
  * 下单客户变更事件 payload。
158
158
  * - `patch`:tempOrder 上的协议字段视图(会随订单提交)
159
159
  * - `snapshot`:UI 富字段快照(仅本地,不随订单提交)
160
- * - `source`:缺省表示真实业务变更;`detailHydrate` 仅表示打开详情时快照已就绪
161
160
  * 清空时整个 payload 为 null。
162
161
  */
163
162
  export interface OrderCustomerChangePayload {
164
163
  patch: OrderCustomerView;
165
164
  snapshot: ICustomer | null;
166
- source?: 'detailHydrate';
167
165
  }
168
166
  export interface OrderScanCodeResult {
169
167
  isAvailable: boolean;
@@ -330,6 +328,8 @@ export type AddProductBookingInput = Record<string, any>;
330
328
  */
331
329
  export interface AddProductToOrderOptions {
332
330
  insertAfterProductUid?: string;
331
+ /** 跳过同商品/规格匹配,始终新增购物车行。 */
332
+ disableMerge?: boolean;
333
333
  }
334
334
  /**
335
335
  * 删除商品后的可选位置保持策略。
@@ -60,7 +60,6 @@ export var OrderHooks = /*#__PURE__*/function (OrderHooks) {
60
60
  * 下单客户变更事件 payload。
61
61
  * - `patch`:tempOrder 上的协议字段视图(会随订单提交)
62
62
  * - `snapshot`:UI 富字段快照(仅本地,不随订单提交)
63
- * - `source`:缺省表示真实业务变更;`detailHydrate` 仅表示打开详情时快照已就绪
64
63
  * 清空时整个 payload 为 null。
65
64
  */
66
65
 
@@ -1124,7 +1124,12 @@ export function buildSubmitPayload(params) {
1124
1124
  var _tempOrder$bookings;
1125
1125
  // 如果外部没有传递 types,根据订单里当前是否有 bookings 来决定是 appointment_booking 还是 virtual
1126
1126
  if (tempOrder !== null && tempOrder !== void 0 && (_tempOrder$bookings = tempOrder.bookings) !== null && _tempOrder$bookings !== void 0 && _tempOrder$bookings.length) {
1127
- submitType = 'appointment_booking';
1127
+ // 260807 如果 biz 是堂食,type 使用table-order
1128
+ if (businessCode === 'dine_in') {
1129
+ submitType = 'table-order';
1130
+ } else {
1131
+ submitType = 'appointment_booking';
1132
+ }
1128
1133
  } else {
1129
1134
  submitType = 'virtual';
1130
1135
  }
@@ -2126,23 +2126,12 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
2126
2126
  return !_this12.isPersistedOrderProduct(product);
2127
2127
  });
2128
2128
  if (hasDraftProduct) return false;
2129
-
2130
- // 编辑详情 hydrate 时,商品行上的历史券卡会被还原为 isEditMode=true、
2131
- // isSelected=true 的只读记录。它们表示“该折扣已在原订单结算”,不是用户在
2132
- // 当前编辑会话中新做的选择,不能据此放行刚从 prepare/config 拉回来的折扣。
2133
- // 否则后续 Rules.calcDiscount 会把没有 isManualSelect 标记的可用 runtime 卡
2134
- // 当作自动候选,再次写入 tempOrder。这里只识别非 isEditMode 的 runtime 状态;
2135
- // 新建单、编辑态新增商品以及用户本次明确选择/取消折扣的原有流程保持不变。
2136
- var hasRuntimeDiscountSelection = params.currentDiscountList.some(function (discount) {
2137
- return !discount.isEditMode && (discount.isSelected || discount.isManualSelect);
2129
+ var hasSelectedDiscount = params.currentDiscountList.some(function (discount) {
2130
+ return discount.isSelected || discount.isEditMode || discount.isManualSelect;
2138
2131
  });
2139
- if (hasRuntimeDiscountSelection) return false;
2140
-
2141
- // nextDiscountList 已经合并了历史只读折扣与本次获取的 runtime 折扣,
2142
- // 因此这里同样必须排除 isEditMode;只有 runtime 条目已有明确选择状态时,
2143
- // 才允许继续进入折扣重算。
2132
+ if (hasSelectedDiscount) return false;
2144
2133
  return !params.nextDiscountList.some(function (discount) {
2145
- return !discount.isEditMode && (discount.isSelected || discount.isManualSelect);
2134
+ return discount.isSelected || discount.isEditMode || discount.isManualSelect;
2146
2135
  });
2147
2136
  }
2148
2137
  }, {
@@ -1,4 +1,9 @@
1
1
  import type { OrderProduct } from '../../../modules/Order/types';
2
+ /**
3
+ * 运行态商品行标记:该行由“不合并商品”加车策略创建,促销重算时必须保持独立。
4
+ * `normalizeSubmitProduct` 会按白名单裁剪 metadata,不会把此字段提交到后端。
5
+ */
6
+ export declare const PRODUCT_LINE_MERGE_DISABLED_METADATA_KEY = "_productLineMergeDisabled";
2
7
  /**
3
8
  * Cart promotion 工具集(OS 内部纯函数)
4
9
  *
@@ -23,6 +23,12 @@ import { cloneDeep } from 'lodash-es';
23
23
  import { composeLinePrice, createUuidV4, getProductSkuOptions, sumOptionUnitPrice } from "../../../modules/Order/utils";
24
24
  import { buildProductLineFingerprint, getSafeProductNum } from "../../ScanOrder/utils";
25
25
 
26
+ /**
27
+ * 运行态商品行标记:该行由“不合并商品”加车策略创建,促销重算时必须保持独立。
28
+ * `normalizeSubmitProduct` 会按白名单裁剪 metadata,不会把此字段提交到后端。
29
+ */
30
+ export var PRODUCT_LINE_MERGE_DISABLED_METADATA_KEY = '_productLineMergeDisabled';
31
+
26
32
  /**
27
33
  * Cart promotion 工具集(OS 内部纯函数)
28
34
  *
@@ -483,10 +489,13 @@ function hasGoodPassDiscount(product) {
483
489
  }
484
490
 
485
491
  /**
486
- * 商品券、自定义商品、称重行以及编辑订单历史行都有各自的促销合并边界。
492
+ * 不合并商品、商品券、自定义商品、称重行以及编辑订单历史行都有各自的促销合并边界。
487
493
  */
488
494
  function getPromotionLineMergeBoundary(product) {
489
- var _product$product_sku, _product$metadata3;
495
+ var _product$metadata3, _product$product_sku, _product$metadata4;
496
+ if ((product === null || product === void 0 || (_product$metadata3 = product.metadata) === null || _product$metadata3 === void 0 ? void 0 : _product$metadata3[PRODUCT_LINE_MERGE_DISABLED_METADATA_KEY]) === true) {
497
+ return "separate:".concat(getOrderProductUid(product));
498
+ }
490
499
  if ((product === null || product === void 0 ? void 0 : product.product_id) === undefined || (product === null || product === void 0 ? void 0 : product.product_id) === null) {
491
500
  return "custom:".concat(getOrderProductUid(product));
492
501
  }
@@ -496,7 +505,7 @@ function getPromotionLineMergeBoundary(product) {
496
505
  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
506
  return "weighing:".concat(getOrderProductUid(product));
498
507
  }
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 '';
508
+ if ((product === null || product === void 0 || (_product$metadata4 = product.metadata) === null || _product$metadata4 === void 0 ? void 0 : _product$metadata4.is_edit_for_runtime) !== true) return '';
500
509
  return "edit:".concat(getOrderProductUid(product));
501
510
  }
502
511
  function isPersistedGeneratedVoucher(product) {
@@ -921,13 +930,13 @@ export function resolveStrategyEligibleProducts(matched) {
921
930
  export function calculateUnfulfilledPromotions(processedProducts, applicableStrategiesResult, mainProducts) {
922
931
  var unfulfilledMap = new Map();
923
932
  var _loop2 = function _loop2() {
924
- var _product$metadata4, _ref13, _product$_originalPro, _product$metadata5, _product$num2;
933
+ var _product$metadata5, _ref13, _product$_originalPro, _product$metadata6, _product$num2;
925
934
  var product = processedProducts[i];
926
- var promotion = product === null || product === void 0 || (_product$metadata4 = product.metadata) === null || _product$metadata4 === void 0 ? void 0 : _product$metadata4._promotion;
935
+ var promotion = product === null || product === void 0 || (_product$metadata5 = product.metadata) === null || _product$metadata5 === void 0 ? void 0 : _product$metadata5._promotion;
927
936
  if (!promotion || promotion.inPromotion !== false) return 0; // continue
928
937
  var strategyId = promotion.strategyId;
929
938
  if (!strategyId) return 0; // continue
930
- var lookupUid = String((_ref13 = (_product$_originalPro = product === null || product === void 0 ? void 0 : product._originalProductUid) !== null && _product$_originalPro !== void 0 ? _product$_originalPro : product === null || product === void 0 || (_product$metadata5 = product.metadata) === null || _product$metadata5 === void 0 ? void 0 : _product$metadata5.unique_identification_number) !== null && _ref13 !== void 0 ? _ref13 : '');
939
+ var lookupUid = String((_ref13 = (_product$_originalPro = product === null || product === void 0 ? void 0 : product._originalProductUid) !== null && _product$_originalPro !== void 0 ? _product$_originalPro : product === null || product === void 0 || (_product$metadata6 = product.metadata) === null || _product$metadata6 === void 0 ? void 0 : _product$metadata6.unique_identification_number) !== null && _ref13 !== void 0 ? _ref13 : '');
931
940
  var originalIndex = mainProducts.findIndex(function (item) {
932
941
  return getOrderProductUid(item) === lookupUid;
933
942
  });
@@ -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 | 1 | 5 | 2 | 4 | 3 | 6;
329
+ weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
330
330
  }[]>;
331
331
  submitTimeSlot(timeSlots: TimeSliceItem): void;
332
332
  private getScheduleDataByIds;
@@ -3,7 +3,7 @@ import { BookingTicketCartView, BookingTicketProductCatalogView, BookingTicketSt
3
3
  import type { ProductData } from '../../modules';
4
4
  import type { OpenDataConfig } from '../../modules/OpenData';
5
5
  import { type BookingContextConfig, type BookingContextDateInput, type BookingContextResource, type BookingContextResourceMap, type BookingContextState, type InitBookingContextParams, type LoadBookingConfigParams, type LoadBookingResourcesParams, type ResourceError, type BookingCalcContext } from '../../modules/BookingContext';
6
- import type { OrderCustomerView, OrderCustomerChangePayload } from '../../modules/Order/types';
6
+ import type { OrderCustomerView } from '../../modules/Order/types';
7
7
  import { BaseSalesImpl } from '../BaseSales';
8
8
  import type { BaseSalesScanCodeResult } from '../BaseSales/types';
9
9
  import type { ISalesDetail } from '../BaseSales/utils/parseSalesResponse';
@@ -260,9 +260,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
260
260
  * 同时透传 OrderModule 内部 emit 的 `order:onOrderCustomerChange` 之外,
261
261
  * 在 BookingTicket 命名空间也 emit 一次,方便上层统一从 Solution 订阅。
262
262
  */
263
- setOrderCustomer(customer: ICustomer | null, options?: {
264
- source?: OrderCustomerChangePayload['source'];
265
- }): void;
263
+ setOrderCustomer(customer: ICustomer | null): void;
266
264
  /**
267
265
  * 读取 tempOrder 上的下单客户协议字段;customer_id 缺失时返回 null。
268
266
  */
@@ -453,7 +451,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
453
451
  * 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
454
452
  * 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
455
453
  */
456
- decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
454
+ decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
455
+ action: "reloadCatalog";
456
+ } | {
457
+ action: "add";
458
+ cacheItem: any;
459
+ } | {
460
+ action: "requiresDetail";
461
+ payload: AddProductRequiresDetailPayload;
462
+ } | {
463
+ action: "requiresBookingEdit";
464
+ cacheItem: any;
465
+ payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
466
+ };
457
467
  /** 规格弹窗 callback 后的第二段决策。 */
458
468
  decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
459
469
  /**
@@ -41,7 +41,7 @@ import { handleGlobalScan, handleCustomerScan, handleUniversalScan } from "./uti
41
41
  import scanCache from "./utils/scan/scanCache";
42
42
  import { formatGlobalScanResult } from "./utils/scan/formatGlobalScan";
43
43
  import { applyGlobalScan } from "./utils/scan/applyGlobalScan";
44
- import { buildCartView } from "./utils/cartView";
44
+ import { buildCartView, isWalkInCustomer } from "./utils/cartView";
45
45
  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";
46
46
  import { buildCacheItemFromOrderLine as buildCacheItemFromOrderLineUtil } from "../../modules/BookingContext/utils/buildCacheItemFromOrderLine";
47
47
  import { buildSessionCatalogStaleInfo, isSessionCatalogDateStale } from "./utils/sessionCatalogStale";
@@ -542,12 +542,7 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
542
542
  country_calling_code: selectedCustomer === null || selectedCustomer === void 0 ? void 0 : selectedCustomer.country_calling_code
543
543
  });
544
544
  customerModule.setSelectedCustomer(customer);
545
- // 详情 hydrate 后仍需广播一次,让 CustomerContext 等 UI 订阅方拿到刚补齐的
546
- // customerSnapshot;但它不是用户主动切换客户。通过 source 明确标记初始化事件,
547
- // 商品报价/折扣订阅方即可跳过 prepare/config,其他旧订阅方仍可照常刷新 UI。
548
- this.setOrderCustomer(customer, {
549
- source: 'detailHydrate'
550
- });
545
+ this.setOrderCustomer(customer);
551
546
  // await this.store.order.saveDraft();
552
547
  }
553
548
  return _context6.abrupt("return", sales);
@@ -683,7 +678,13 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
683
678
  try {
684
679
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
685
680
  var item = _step.value;
686
- var topLevelId = Number(item.customer_id);
681
+ var rawCustomerId = item.customer_id;
682
+ if (!rawCustomerId || isWalkInCustomer({
683
+ id: rawCustomerId
684
+ })) {
685
+ continue;
686
+ }
687
+ var topLevelId = Number(rawCustomerId);
687
688
  if (Number.isFinite(topLevelId) && topLevelId > 0) {
688
689
  return topLevelId;
689
690
  }
@@ -1563,7 +1564,7 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
1563
1564
  */
1564
1565
  }, {
1565
1566
  key: "setOrderCustomer",
1566
- value: function setOrderCustomer(customer, options) {
1567
+ value: function setOrderCustomer(customer) {
1567
1568
  var _this$store$order$get3,
1568
1569
  _this3 = this;
1569
1570
  if (!customer) {
@@ -1586,16 +1587,12 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
1586
1587
  var snapshotReplenished = !snapshotBeforeSet && Boolean(snapshotAfterOrderSet);
1587
1588
  if (snapshotReplenished) {
1588
1589
  var _next2 = this.buildOrderCustomerPayload();
1589
- this.core.effects.emit("".concat(this.name, ":onOrderCustomerChange"), _next2 && options !== null && options !== void 0 && options.source ? _objectSpread(_objectSpread({}, _next2), {}, {
1590
- source: options.source
1591
- }) : _next2);
1590
+ this.core.effects.emit("".concat(this.name, ":onOrderCustomerChange"), _next2);
1592
1591
  }
1593
1592
  return;
1594
1593
  }
1595
1594
  var next = this.buildOrderCustomerPayload();
1596
- this.core.effects.emit("".concat(this.name, ":onOrderCustomerChange"), next && options !== null && options !== void 0 && options.source ? _objectSpread(_objectSpread({}, next), {}, {
1597
- source: options.source
1598
- }) : next);
1595
+ this.core.effects.emit("".concat(this.name, ":onOrderCustomerChange"), next);
1599
1596
  this.refreshDiscountConfigAfterOrderCustomerChange(patch.customer_id);
1600
1597
  // 客户切换可能改变可用促销/赠品;触发一次重算(recursion-safe)。
1601
1598
  var promotionRefreshTask = this.store.order.applyPromotion().then(function () {
package/lib/core/index.js CHANGED
@@ -50,6 +50,7 @@ var PisellOSCore = class {
50
50
  this.serverOptions = options.server;
51
51
  }
52
52
  this.initialize(options);
53
+ console.log("constructor123456543");
53
54
  }
54
55
  initialize(options) {
55
56
  if (options == null ? void 0 : options.plugins) {
@@ -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
- });
@@ -512,7 +512,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
512
512
  generateIdempotencyToken(): string;
513
513
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
514
514
  createOrder(params: CommitOrderParams['query']): {
515
- type: "virtual" | "appointment_booking";
515
+ type: "appointment_booking" | "virtual";
516
516
  platform: string;
517
517
  sales_channel: string;
518
518
  order_sales_channel: string;
@@ -3048,7 +3048,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3048
3048
  var _a, _b, _c, _d, _e, _f;
3049
3049
  const linked = booking ? this.createLinkedProductAndBooking({ product, booking }) : null;
3050
3050
  const productToAdd = (linked == null ? void 0 : linked.product) || product;
3051
- const incomingFingerprint = (0, import_utils3.buildProductLineFingerprint)(
3051
+ const disableMerge = (options == null ? void 0 : options.disableMerge) === true;
3052
+ const incomingFingerprint = disableMerge ? "" : (0, import_utils3.buildProductLineFingerprint)(
3052
3053
  (0, import_utils.getProductSkuOptions)(productToAdd),
3053
3054
  productToAdd.product_bundle
3054
3055
  );
@@ -3056,6 +3057,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3056
3057
  productToAdd,
3057
3058
  (0, import_utils3.normalizeOrderProduct)(productToAdd)
3058
3059
  );
3060
+ if (disableMerge) {
3061
+ normalizedIncoming.metadata = {
3062
+ ...normalizedIncoming.metadata || {},
3063
+ [import_cartPromotion.PRODUCT_LINE_MERGE_DISABLED_METADATA_KEY]: true
3064
+ };
3065
+ }
3059
3066
  const isWeighingProduct = Number(((_a = normalizedIncoming.product_sku) == null ? void 0 : _a.open_sold_weight) || 0) === 1;
3060
3067
  const netWeight = Number((_b = normalizedIncoming.product_sku) == null ? void 0 : _b.net_weight);
3061
3068
  if (isWeighingProduct && (!Number.isFinite(netWeight) || netWeight <= 0)) {
@@ -3079,7 +3086,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3079
3086
  const hasIncomingManualProductDiscount = isManualProductDiscountProduct(normalizedIncoming);
3080
3087
  const hasIncomingBookingUid = this.hasLinkedBookingUid(productToAdd) || this.hasLinkedBookingUid(normalizedIncoming);
3081
3088
  const isIncomingCustomItem = ((_e = (_d = productToAdd.metadata) == null ? void 0 : _d.origin) == null ? void 0 : _e.isCustomItem) === true || ((_f = productToAdd._origin) == null ? void 0 : _f.isCustomItem) === true;
3082
- const shouldForceNewLine = !!booking || hasIncomingProductNote || hasIncomingManualProductDiscount || hasIncomingBookingUid || isIncomingCustomItem || isWeighingProduct;
3089
+ const shouldForceNewLine = disableMerge || !!booking || hasIncomingProductNote || hasIncomingManualProductDiscount || hasIncomingBookingUid || isIncomingCustomItem || isWeighingProduct;
3083
3090
  const matchedIndex = hasIncomingGoodPass || shouldForceNewLine ? -1 : tempOrder.products.findIndex((item) => {
3084
3091
  var _a2;
3085
3092
  if (this.hasGoodPassDiscount(item))
@@ -3235,7 +3242,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3235
3242
  tempOrder,
3236
3243
  singleLine,
3237
3244
  (0, import_lodash_es.cloneDeep)(booking),
3238
- { insertAtIndex }
3245
+ { insertAtIndex, disableMerge: options == null ? void 0 : options.disableMerge }
3239
3246
  );
3240
3247
  if (appendResult2)
3241
3248
  await appendResult2;
@@ -3250,7 +3257,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3250
3257
  tempOrder,
3251
3258
  product,
3252
3259
  booking,
3253
- { insertAtIndex }
3260
+ { insertAtIndex, disableMerge: options == null ? void 0 : options.disableMerge }
3254
3261
  );
3255
3262
  if (appendResult)
3256
3263
  await appendResult;
@@ -157,13 +157,11 @@ export interface OrderCustomerPatch {
157
157
  * 下单客户变更事件 payload。
158
158
  * - `patch`:tempOrder 上的协议字段视图(会随订单提交)
159
159
  * - `snapshot`:UI 富字段快照(仅本地,不随订单提交)
160
- * - `source`:缺省表示真实业务变更;`detailHydrate` 仅表示打开详情时快照已就绪
161
160
  * 清空时整个 payload 为 null。
162
161
  */
163
162
  export interface OrderCustomerChangePayload {
164
163
  patch: OrderCustomerView;
165
164
  snapshot: ICustomer | null;
166
- source?: 'detailHydrate';
167
165
  }
168
166
  export interface OrderScanCodeResult {
169
167
  isAvailable: boolean;
@@ -330,6 +328,8 @@ export type AddProductBookingInput = Record<string, any>;
330
328
  */
331
329
  export interface AddProductToOrderOptions {
332
330
  insertAfterProductUid?: string;
331
+ /** 跳过同商品/规格匹配,始终新增购物车行。 */
332
+ disableMerge?: boolean;
333
333
  }
334
334
  /**
335
335
  * 删除商品后的可选位置保持策略。
@@ -994,7 +994,11 @@ function buildSubmitPayload(params) {
994
994
  let submitType = type ?? tempOrder.type;
995
995
  if (!submitType) {
996
996
  if ((_a = tempOrder == null ? void 0 : tempOrder.bookings) == null ? void 0 : _a.length) {
997
- submitType = "appointment_booking";
997
+ if (businessCode === "dine_in") {
998
+ submitType = "table-order";
999
+ } else {
1000
+ submitType = "appointment_booking";
1001
+ }
998
1002
  } else {
999
1003
  submitType = "virtual";
1000
1004
  }
@@ -1494,13 +1494,13 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1494
1494
  const hasDraftProduct = params.products.some((product) => !this.isPersistedOrderProduct(product));
1495
1495
  if (hasDraftProduct)
1496
1496
  return false;
1497
- const hasRuntimeDiscountSelection = params.currentDiscountList.some(
1498
- (discount) => !discount.isEditMode && (discount.isSelected || discount.isManualSelect)
1497
+ const hasSelectedDiscount = params.currentDiscountList.some(
1498
+ (discount) => discount.isSelected || discount.isEditMode || discount.isManualSelect
1499
1499
  );
1500
- if (hasRuntimeDiscountSelection)
1500
+ if (hasSelectedDiscount)
1501
1501
  return false;
1502
1502
  return !params.nextDiscountList.some(
1503
- (discount) => !discount.isEditMode && (discount.isSelected || discount.isManualSelect)
1503
+ (discount) => discount.isSelected || discount.isEditMode || discount.isManualSelect
1504
1504
  );
1505
1505
  }
1506
1506
  mergeCurrentDiscountSelectionState(discountList, currentDiscountList) {
@@ -1,4 +1,9 @@
1
1
  import type { OrderProduct } from '../../../modules/Order/types';
2
+ /**
3
+ * 运行态商品行标记:该行由“不合并商品”加车策略创建,促销重算时必须保持独立。
4
+ * `normalizeSubmitProduct` 会按白名单裁剪 metadata,不会把此字段提交到后端。
5
+ */
6
+ export declare const PRODUCT_LINE_MERGE_DISABLED_METADATA_KEY = "_productLineMergeDisabled";
2
7
  /**
3
8
  * Cart promotion 工具集(OS 内部纯函数)
4
9
  *
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  // src/solution/BaseSales/utils/cartPromotion.ts
30
30
  var cartPromotion_exports = {};
31
31
  __export(cartPromotion_exports, {
32
+ PRODUCT_LINE_MERGE_DISABLED_METADATA_KEY: () => PRODUCT_LINE_MERGE_DISABLED_METADATA_KEY,
32
33
  appendPromotionTags: () => appendPromotionTags,
33
34
  buildConsolidateKeyForPromotion: () => buildConsolidateKeyForPromotion,
34
35
  calculateUnfulfilledPromotions: () => calculateUnfulfilledPromotions,
@@ -46,6 +47,7 @@ var import_decimal = __toESM(require("decimal.js"));
46
47
  var import_lodash_es = require("lodash-es");
47
48
  var import_utils = require("../../../modules/Order/utils");
48
49
  var import_utils2 = require("../../ScanOrder/utils");
50
+ var PRODUCT_LINE_MERGE_DISABLED_METADATA_KEY = "_productLineMergeDisabled";
49
51
  function getOrderProductBasePrice(product) {
50
52
  const metadata = (product == null ? void 0 : product.metadata) || {};
51
53
  const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product)).toNumber();
@@ -382,17 +384,20 @@ function hasGoodPassDiscount(product) {
382
384
  );
383
385
  }
384
386
  function getPromotionLineMergeBoundary(product) {
385
- var _a, _b;
387
+ var _a, _b, _c;
388
+ if (((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a[PRODUCT_LINE_MERGE_DISABLED_METADATA_KEY]) === true) {
389
+ return `separate:${getOrderProductUid(product)}`;
390
+ }
386
391
  if ((product == null ? void 0 : product.product_id) === void 0 || (product == null ? void 0 : product.product_id) === null) {
387
392
  return `custom:${getOrderProductUid(product)}`;
388
393
  }
389
394
  if (hasGoodPassDiscount(product)) {
390
395
  return `good-pass:${getOrderProductUid(product)}`;
391
396
  }
392
- if (Number(((_a = product == null ? void 0 : product.product_sku) == null ? void 0 : _a.open_sold_weight) || 0) === 1) {
397
+ if (Number(((_b = product == null ? void 0 : product.product_sku) == null ? void 0 : _b.open_sold_weight) || 0) === 1) {
393
398
  return `weighing:${getOrderProductUid(product)}`;
394
399
  }
395
- if (((_b = product == null ? void 0 : product.metadata) == null ? void 0 : _b.is_edit_for_runtime) !== true)
400
+ if (((_c = product == null ? void 0 : product.metadata) == null ? void 0 : _c.is_edit_for_runtime) !== true)
396
401
  return "";
397
402
  return `edit:${getOrderProductUid(product)}`;
398
403
  }
@@ -1065,6 +1070,7 @@ function processCartPromotion(list, evaluator, options) {
1065
1070
  }
1066
1071
  // Annotate the CommonJS export names for ESM import in node:
1067
1072
  0 && (module.exports = {
1073
+ PRODUCT_LINE_MERGE_DISABLED_METADATA_KEY,
1068
1074
  appendPromotionTags,
1069
1075
  buildConsolidateKeyForPromotion,
1070
1076
  calculateUnfulfilledPromotions,
@@ -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 | 1 | 5 | 2 | 4 | 3 | 6;
329
+ weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
330
330
  }[]>;
331
331
  submitTimeSlot(timeSlots: TimeSliceItem): void;
332
332
  private getScheduleDataByIds;
@@ -3,7 +3,7 @@ import { BookingTicketCartView, BookingTicketProductCatalogView, BookingTicketSt
3
3
  import type { ProductData } from '../../modules';
4
4
  import type { OpenDataConfig } from '../../modules/OpenData';
5
5
  import { type BookingContextConfig, type BookingContextDateInput, type BookingContextResource, type BookingContextResourceMap, type BookingContextState, type InitBookingContextParams, type LoadBookingConfigParams, type LoadBookingResourcesParams, type ResourceError, type BookingCalcContext } from '../../modules/BookingContext';
6
- import type { OrderCustomerView, OrderCustomerChangePayload } from '../../modules/Order/types';
6
+ import type { OrderCustomerView } from '../../modules/Order/types';
7
7
  import { BaseSalesImpl } from '../BaseSales';
8
8
  import type { BaseSalesScanCodeResult } from '../BaseSales/types';
9
9
  import type { ISalesDetail } from '../BaseSales/utils/parseSalesResponse';
@@ -260,9 +260,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
260
260
  * 同时透传 OrderModule 内部 emit 的 `order:onOrderCustomerChange` 之外,
261
261
  * 在 BookingTicket 命名空间也 emit 一次,方便上层统一从 Solution 订阅。
262
262
  */
263
- setOrderCustomer(customer: ICustomer | null, options?: {
264
- source?: OrderCustomerChangePayload['source'];
265
- }): void;
263
+ setOrderCustomer(customer: ICustomer | null): void;
266
264
  /**
267
265
  * 读取 tempOrder 上的下单客户协议字段;customer_id 缺失时返回 null。
268
266
  */
@@ -453,7 +451,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
453
451
  * 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
454
452
  * 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
455
453
  */
456
- decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
454
+ decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
455
+ action: "reloadCatalog";
456
+ } | {
457
+ action: "add";
458
+ cacheItem: any;
459
+ } | {
460
+ action: "requiresDetail";
461
+ payload: AddProductRequiresDetailPayload;
462
+ } | {
463
+ action: "requiresBookingEdit";
464
+ cacheItem: any;
465
+ payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
466
+ };
457
467
  /** 规格弹窗 callback 后的第二段决策。 */
458
468
  decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
459
469
  /**
@@ -343,7 +343,7 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
343
343
  country_calling_code: selectedCustomer == null ? void 0 : selectedCustomer.country_calling_code
344
344
  };
345
345
  customerModule.setSelectedCustomer(customer);
346
- this.setOrderCustomer(customer, { source: "detailHydrate" });
346
+ this.setOrderCustomer(customer);
347
347
  }
348
348
  return sales;
349
349
  }
@@ -392,7 +392,11 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
392
392
  }
393
393
  getDiscountCustomerId(discounts) {
394
394
  for (const item of discounts) {
395
- const topLevelId = Number(item.customer_id);
395
+ const rawCustomerId = item.customer_id;
396
+ if (!rawCustomerId || (0, import_cartView.isWalkInCustomer)({ id: rawCustomerId })) {
397
+ continue;
398
+ }
399
+ const topLevelId = Number(rawCustomerId);
396
400
  if (Number.isFinite(topLevelId) && topLevelId > 0) {
397
401
  return topLevelId;
398
402
  }
@@ -891,7 +895,7 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
891
895
  * 同时透传 OrderModule 内部 emit 的 `order:onOrderCustomerChange` 之外,
892
896
  * 在 BookingTicket 命名空间也 emit 一次,方便上层统一从 Solution 订阅。
893
897
  */
894
- setOrderCustomer(customer, options) {
898
+ setOrderCustomer(customer) {
895
899
  var _a;
896
900
  if (!customer) {
897
901
  this.clearOrderCustomer();
@@ -911,18 +915,12 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
911
915
  const snapshotReplenished = !snapshotBeforeSet && Boolean(snapshotAfterOrderSet);
912
916
  if (snapshotReplenished) {
913
917
  const next2 = this.buildOrderCustomerPayload();
914
- this.core.effects.emit(
915
- `${this.name}:onOrderCustomerChange`,
916
- next2 && (options == null ? void 0 : options.source) ? { ...next2, source: options.source } : next2
917
- );
918
+ this.core.effects.emit(`${this.name}:onOrderCustomerChange`, next2);
918
919
  }
919
920
  return;
920
921
  }
921
922
  const next = this.buildOrderCustomerPayload();
922
- this.core.effects.emit(
923
- `${this.name}:onOrderCustomerChange`,
924
- next && (options == null ? void 0 : options.source) ? { ...next, source: options.source } : next
925
- );
923
+ this.core.effects.emit(`${this.name}:onOrderCustomerChange`, next);
926
924
  this.refreshDiscountConfigAfterOrderCustomerChange(patch.customer_id);
927
925
  const promotionRefreshTask = this.store.order.applyPromotion().then(() => void 0);
928
926
  this.orderCustomerPromotionRefreshInFlight = promotionRefreshTask;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.2.281",
4
+ "version": "2.2.283",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",