@pisell/pisellos 2.2.267 → 2.2.268

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.
@@ -3587,7 +3587,7 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
3587
3587
  }, {
3588
3588
  key: "addProductToOrder",
3589
3589
  value: function () {
3590
- var _addProductToOrder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee39(product, booking) {
3590
+ var _addProductToOrder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee39(product, booking, options) {
3591
3591
  var products;
3592
3592
  return _regeneratorRuntime().wrap(function _callee39$(_context39) {
3593
3593
  while (1) switch (_context39.prev = _context39.next) {
@@ -3600,7 +3600,7 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
3600
3600
  throw new Error('order 模块未初始化');
3601
3601
  case 3:
3602
3602
  _context39.next = 5;
3603
- return this.store.order.addProductToOrder(product, booking);
3603
+ return this.store.order.addProductToOrder(product, booking, options);
3604
3604
  case 5:
3605
3605
  products = _context39.sent;
3606
3606
  return _context39.abrupt("return", products);
@@ -3614,7 +3614,7 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
3614
3614
  }
3615
3615
  }, _callee39, this, [[0, 9]]);
3616
3616
  }));
3617
- function addProductToOrder(_x31, _x32) {
3617
+ function addProductToOrder(_x31, _x32, _x33) {
3618
3618
  return _addProductToOrder.apply(this, arguments);
3619
3619
  }
3620
3620
  return addProductToOrder;
@@ -3649,7 +3649,7 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
3649
3649
  }
3650
3650
  }, _callee40, this, [[0, 9]]);
3651
3651
  }));
3652
- function updateOrderProduct(_x33) {
3652
+ function updateOrderProduct(_x34) {
3653
3653
  return _updateOrderProduct.apply(this, arguments);
3654
3654
  }
3655
3655
  return updateOrderProduct;
@@ -3684,7 +3684,7 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
3684
3684
  }
3685
3685
  }, _callee41, this, [[0, 9]]);
3686
3686
  }));
3687
- function updateOrderProducts(_x34) {
3687
+ function updateOrderProducts(_x35) {
3688
3688
  return _updateOrderProducts.apply(this, arguments);
3689
3689
  }
3690
3690
  return updateOrderProducts;
@@ -3719,7 +3719,7 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
3719
3719
  }
3720
3720
  }, _callee42, this, [[0, 9]]);
3721
3721
  }));
3722
- function updateOrderProductQuantity(_x35) {
3722
+ function updateOrderProductQuantity(_x36) {
3723
3723
  return _updateOrderProductQuantity.apply(this, arguments);
3724
3724
  }
3725
3725
  return updateOrderProductQuantity;
@@ -3777,7 +3777,7 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
3777
3777
  }
3778
3778
  }, _callee43, this, [[0, 11]]);
3779
3779
  }));
3780
- function setOrderProductLineNote(_x36, _x37) {
3780
+ function setOrderProductLineNote(_x37, _x38) {
3781
3781
  return _setOrderProductLineNote.apply(this, arguments);
3782
3782
  }
3783
3783
  return setOrderProductLineNote;
@@ -3792,7 +3792,7 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
3792
3792
  }, {
3793
3793
  key: "removeProductsFromOrder",
3794
3794
  value: (function () {
3795
- var _removeProductsFromOrder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee44(identities) {
3795
+ var _removeProductsFromOrder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee44(identities, options) {
3796
3796
  return _regeneratorRuntime().wrap(function _callee44$(_context44) {
3797
3797
  while (1) switch (_context44.prev = _context44.next) {
3798
3798
  case 0:
@@ -3804,7 +3804,7 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
3804
3804
  throw new Error('order 模块未初始化');
3805
3805
  case 3:
3806
3806
  _context44.next = 5;
3807
- return this.store.order.removeProductsFromOrder(identities);
3807
+ return this.store.order.removeProductsFromOrder(identities, options);
3808
3808
  case 5:
3809
3809
  return _context44.abrupt("return", _context44.sent);
3810
3810
  case 8:
@@ -3817,7 +3817,7 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
3817
3817
  }
3818
3818
  }, _callee44, this, [[0, 8]]);
3819
3819
  }));
3820
- function removeProductsFromOrder(_x38) {
3820
+ function removeProductsFromOrder(_x39, _x40) {
3821
3821
  return _removeProductsFromOrder.apply(this, arguments);
3822
3822
  }
3823
3823
  return removeProductsFromOrder;
@@ -3825,18 +3825,18 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
3825
3825
  }, {
3826
3826
  key: "removeProductFromOrder",
3827
3827
  value: function () {
3828
- var _removeProductFromOrder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee45(identity) {
3828
+ var _removeProductFromOrder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee45(identity, options) {
3829
3829
  return _regeneratorRuntime().wrap(function _callee45$(_context45) {
3830
3830
  while (1) switch (_context45.prev = _context45.next) {
3831
3831
  case 0:
3832
- return _context45.abrupt("return", this.removeProductsFromOrder([identity]));
3832
+ return _context45.abrupt("return", this.removeProductsFromOrder([identity], options));
3833
3833
  case 1:
3834
3834
  case "end":
3835
3835
  return _context45.stop();
3836
3836
  }
3837
3837
  }, _callee45, this);
3838
3838
  }));
3839
- function removeProductFromOrder(_x39) {
3839
+ function removeProductFromOrder(_x41, _x42) {
3840
3840
  return _removeProductFromOrder.apply(this, arguments);
3841
3841
  }
3842
3842
  return removeProductFromOrder;
@@ -3999,7 +3999,7 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
3999
3999
  }
4000
4000
  }, _callee48, this);
4001
4001
  }));
4002
- function setOtherParams(_x40) {
4002
+ function setOtherParams(_x43) {
4003
4003
  return _setOtherParams.apply(this, arguments);
4004
4004
  }
4005
4005
  return setOtherParams;
@@ -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 | 4 | 5 | 6;
314
+ weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -322,7 +322,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
322
322
  * 获取当前的客户搜索条件
323
323
  * @returns 当前搜索条件
324
324
  */
325
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
325
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
326
326
  /**
327
327
  * 获取客户列表状态(包含滚动加载相关状态)
328
328
  * @returns 客户状态
@@ -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
- var cartBookings = bookingList.filter(function (booking) {
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
- var product = null;
121
- if (uid !== undefined && uid !== null && uid !== '') {
122
- var key = String(uid);
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
- acc.push(_objectSpread(_objectSpread({}, booking), {}, {
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
- return acc;
152
- }, []);
153
- var items = productLines.filter(function (line) {
145
+ });
146
+ };
147
+ productLines.forEach(function (line) {
154
148
  var _line$metadata6;
155
- // 促销赠品行仅通过主商品 Gift 行展示,不在 items 单独占一行(对齐 legacy `isGift: !!_giftInfo`)
156
- if (isGiftProductLine(line)) return false;
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
- if (uid === undefined || uid === null || uid === '') return true;
160
- return !claimedUids.has(String(uid));
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) {
@@ -3,7 +3,7 @@ import { BaseModule } from '../BaseModule';
3
3
  import { OrderModuleAPI, CommitOrderParams, UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, CheckoutOrderParams, CancelOrderParams, ChangeBookingStatusParams } from './types';
4
4
  import { CartItem } from '../Cart/types';
5
5
  import { type SubmitPayloadEnhancer } from './utils';
6
- import type { OrderAmountSnapshot, AddProductBookingInput, OrderIdentitySnapshot, OrderPaymentSource, OrderSnapshot, OrderSyncState, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, SubmitSalesOrderParams, OrderProduct, OrderProductIdentity, OrderSummary, OrderTempOrder, OrderPaymentData, SendCustomerPayLinkParams, UpdateTempOrderCustomerInput, OrderCustomerPatch, OrderCustomerView, ReplaceTempOrderOptions, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions } from './types';
6
+ import type { OrderAmountSnapshot, AddProductBookingInput, AddProductToOrderOptions, OrderIdentitySnapshot, OrderPaymentSource, OrderSnapshot, OrderSyncState, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, SubmitSalesOrderParams, OrderProduct, OrderProductIdentity, OrderSummary, OrderTempOrder, OrderPaymentData, SendCustomerPayLinkParams, UpdateTempOrderCustomerInput, OrderCustomerPatch, OrderCustomerView, ReplaceTempOrderOptions, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions } from './types';
7
7
  import type { ICustomer } from '../AccountList/types';
8
8
  import type { Discount } from '../Discount/types';
9
9
  import { UnavailableReason } from '../Rules/types';
@@ -374,7 +374,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
374
374
  * await order.addProductToOrder({ product_id: 1, num: 3 }, { start_time: '10:00' });
375
375
  * // → tempOrder.products 新增 3 行,每行 num=1,bookings 3 条
376
376
  */
377
- addProductToOrder(product: Partial<OrderProduct> & OrderProductIdentity, booking?: AddProductBookingInput): Promise<OrderProduct[]>;
377
+ addProductToOrder(product: Partial<OrderProduct> & OrderProductIdentity, booking?: AddProductBookingInput, options?: AddProductToOrderOptions): Promise<OrderProduct[]>;
378
378
  /**
379
379
  * 批量添加商品行,所有行追加完成后只触发一次促销、折扣、summary 重算与持久化。
380
380
  *
@@ -412,8 +412,8 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
412
412
  * @example
413
413
  * await order.removeProductsFromOrder([identityA, identityB]);
414
414
  */
415
- removeProductsFromOrder(identities: OrderProductIdentity[]): Promise<OrderProduct[]>;
416
- removeProductFromOrder(identity: OrderProductIdentity): Promise<OrderProduct[]>;
415
+ removeProductsFromOrder(identities: OrderProductIdentity[], options?: RemoveProductsFromOrderOptions): Promise<OrderProduct[]>;
416
+ removeProductFromOrder(identity: OrderProductIdentity, options?: RemoveProductsFromOrderOptions): Promise<OrderProduct[]>;
417
417
  /**
418
418
  * 仅清空购物车行(products / bookings),不重置整单。
419
419
  * 用于「仅清空商品」;客户、备注、支付等协议字段保持不变。
@@ -468,7 +468,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
468
468
  generateIdempotencyToken(): string;
469
469
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
470
470
  createOrder(params: CommitOrderParams['query']): {
471
- type: "virtual" | "appointment_booking";
471
+ type: "appointment_booking" | "virtual";
472
472
  platform: string;
473
473
  sales_channel: string;
474
474
  order_sales_channel: string;
@@ -541,4 +541,4 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
541
541
  getOrderInfo(order_id: number): Promise<any>;
542
542
  getVouchers(): any[];
543
543
  }
544
- export type { UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, } from './types';
544
+ export type { AddProductToOrderOptions, RemoveProductsFromOrderOptions, UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, } from './types';
@@ -2789,7 +2789,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2789
2789
  * @example
2790
2790
  * await this.appendProductLineToTempOrder(tempOrder, { product_id: 1, num: 1 }, booking);
2791
2791
  */
2792
- async appendProductLineToTempOrder(tempOrder, product, booking) {
2792
+ async appendProductLineToTempOrder(tempOrder, product, booking, options) {
2793
2793
  var _a, _b, _c, _d;
2794
2794
  const linked = booking ? this.createLinkedProductAndBooking({ product, booking }) : null;
2795
2795
  const productToAdd = (linked == null ? void 0 : linked.product) || product;
@@ -2871,7 +2871,16 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2871
2871
  booking_uid: linked.bookingUid
2872
2872
  };
2873
2873
  }
2874
- tempOrder.products = [...tempOrder.products, normalizedIncoming];
2874
+ const insertAtIndex = options == null ? void 0 : options.insertAtIndex;
2875
+ if (Number.isInteger(insertAtIndex) && Number(insertAtIndex) >= 0 && Number(insertAtIndex) < tempOrder.products.length) {
2876
+ tempOrder.products = [
2877
+ ...tempOrder.products.slice(0, insertAtIndex),
2878
+ normalizedIncoming,
2879
+ ...tempOrder.products.slice(insertAtIndex)
2880
+ ];
2881
+ } else {
2882
+ tempOrder.products = [...tempOrder.products, normalizedIncoming];
2883
+ }
2875
2884
  } else {
2876
2885
  const targetProduct = matchedProduct;
2877
2886
  const targetUid = (_d = targetProduct.metadata) == null ? void 0 : _d.unique_identification_number;
@@ -2930,6 +2939,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2930
2939
  tempOrder.products[matchedIndex],
2931
2940
  targetUid
2932
2941
  );
2942
+ if (matchedIndex !== tempOrder.products.length - 1) {
2943
+ const mergedProduct = tempOrder.products[matchedIndex];
2944
+ tempOrder.products = [
2945
+ ...tempOrder.products.slice(0, matchedIndex),
2946
+ ...tempOrder.products.slice(matchedIndex + 1),
2947
+ mergedProduct
2948
+ ];
2949
+ }
2933
2950
  }
2934
2951
  if (linked) {
2935
2952
  tempOrder.bookings = [...tempOrder.bookings || [], linked.booking];
@@ -2942,8 +2959,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2942
2959
  * await order.addProductToOrder({ product_id: 1, num: 3 }, { start_time: '10:00' });
2943
2960
  * // → tempOrder.products 新增 3 行,每行 num=1,bookings 3 条
2944
2961
  */
2945
- async addProductToOrder(product, booking) {
2962
+ async addProductToOrder(product, booking, options) {
2946
2963
  const tempOrder = this.ensureTempOrder();
2964
+ const insertAfterProductUid = options == null ? void 0 : options.insertAfterProductUid;
2965
+ const anchorIndex = booking && insertAfterProductUid ? tempOrder.products.findIndex((line) => {
2966
+ var _a;
2967
+ const uid = ((_a = line.metadata) == null ? void 0 : _a.unique_identification_number) || line.unique_identification_number;
2968
+ return uid !== void 0 && uid !== null && String(uid) === String(insertAfterProductUid);
2969
+ }) : -1;
2970
+ let insertAtIndex = anchorIndex >= 0 ? anchorIndex + 1 : void 0;
2947
2971
  if (booking) {
2948
2972
  const productRecord = product;
2949
2973
  const splitCount = (0, import_utils3.getSafeProductNum)(
@@ -2957,14 +2981,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2957
2981
  await this.appendProductLineToTempOrder(
2958
2982
  tempOrder,
2959
2983
  singleLine,
2960
- (0, import_lodash_es.cloneDeep)(booking)
2984
+ (0, import_lodash_es.cloneDeep)(booking),
2985
+ { insertAtIndex }
2961
2986
  );
2987
+ if (insertAtIndex !== void 0)
2988
+ insertAtIndex += 1;
2962
2989
  }
2963
2990
  await this.finalizeProductOrderMutation(tempOrder);
2964
2991
  return tempOrder.products;
2965
2992
  }
2966
2993
  }
2967
- await this.appendProductLineToTempOrder(tempOrder, product, booking);
2994
+ await this.appendProductLineToTempOrder(
2995
+ tempOrder,
2996
+ product,
2997
+ booking,
2998
+ { insertAtIndex }
2999
+ );
2968
3000
  await this.finalizeProductOrderMutation(tempOrder);
2969
3001
  this.logInfo("addProductToOrder success", {
2970
3002
  product_id: product.product_id,
@@ -3445,7 +3477,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3445
3477
  * @example
3446
3478
  * await order.removeProductsFromOrder([identityA, identityB]);
3447
3479
  */
3448
- async removeProductsFromOrder(identities) {
3480
+ async removeProductsFromOrder(identities, options) {
3449
3481
  var _a, _b, _c, _d;
3450
3482
  const tempOrder = this.ensureTempOrder();
3451
3483
  if (!identities.length) {
@@ -3453,6 +3485,13 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3453
3485
  }
3454
3486
  const productsBeforeRemove = tempOrder.products || [];
3455
3487
  const bookingsBeforeRemove = tempOrder.bookings || [];
3488
+ const preserveDisplayPosition = options == null ? void 0 : options.preserveDisplayPosition;
3489
+ const anchorIndex = preserveDisplayPosition ? productsBeforeRemove.findIndex((item) => {
3490
+ var _a2;
3491
+ const uid = ((_a2 = item.metadata) == null ? void 0 : _a2.unique_identification_number) || item.unique_identification_number;
3492
+ return uid !== void 0 && uid !== null && String(uid) === String(preserveDisplayPosition.anchorProductUid);
3493
+ }) : -1;
3494
+ const productsAfterAnchor = anchorIndex >= 0 ? productsBeforeRemove.slice(anchorIndex + 1) : [];
3456
3495
  const matchedProducts = productsBeforeRemove.filter((item) => {
3457
3496
  return identities.some((identity) => (0, import_utils3.isIdentityMatch)(item, identity));
3458
3497
  });
@@ -3493,14 +3532,37 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3493
3532
  return !(isAddTimeProduct && lineBookingUid !== void 0 && lineBookingUid !== null && linkedBookingUidsToRemove.has(String(lineBookingUid)));
3494
3533
  });
3495
3534
  }
3535
+ if (preserveDisplayPosition && anchorIndex >= 0) {
3536
+ const remainingProductIndex = tempOrder.products.findIndex((item) => {
3537
+ var _a2;
3538
+ const uid = ((_a2 = item.metadata) == null ? void 0 : _a2.unique_identification_number) || item.unique_identification_number;
3539
+ return uid !== void 0 && uid !== null && String(uid) === String(preserveDisplayPosition.remainingProductUid);
3540
+ });
3541
+ if (remainingProductIndex >= 0) {
3542
+ const remainingProduct = tempOrder.products[remainingProductIndex];
3543
+ const nextProduct = productsAfterAnchor.find(
3544
+ (item) => tempOrder.products.includes(item)
3545
+ );
3546
+ const productsWithoutRemaining = [
3547
+ ...tempOrder.products.slice(0, remainingProductIndex),
3548
+ ...tempOrder.products.slice(remainingProductIndex + 1)
3549
+ ];
3550
+ const nextProductIndex = nextProduct ? productsWithoutRemaining.indexOf(nextProduct) : -1;
3551
+ tempOrder.products = nextProductIndex >= 0 ? [
3552
+ ...productsWithoutRemaining.slice(0, nextProductIndex),
3553
+ remainingProduct,
3554
+ ...productsWithoutRemaining.slice(nextProductIndex)
3555
+ ] : [...productsWithoutRemaining, remainingProduct];
3556
+ }
3557
+ }
3496
3558
  await this.finalizeAfterProductsMutation(tempOrder);
3497
3559
  this.logInfo("removeProductsFromOrder success", {
3498
3560
  identities
3499
3561
  });
3500
3562
  return tempOrder.products;
3501
3563
  }
3502
- async removeProductFromOrder(identity) {
3503
- return this.removeProductsFromOrder([identity]);
3564
+ async removeProductFromOrder(identity, options) {
3565
+ return this.removeProductsFromOrder([identity], options);
3504
3566
  }
3505
3567
  /**
3506
3568
  * 仅清空购物车行(products / bookings),不重置整单。
@@ -319,6 +319,24 @@ export interface ReplaceTempOrderOptions {
319
319
  saveDraft?: boolean;
320
320
  }
321
321
  export type AddProductBookingInput = Record<string, any>;
322
+ /**
323
+ * 添加商品行时的顺序控制。
324
+ * 默认追加到 products 尾部;预约数量同步可插入到既有预约组的最新行之后,
325
+ * 避免步进器修改数量改变该组展示位置。
326
+ */
327
+ export interface AddProductToOrderOptions {
328
+ insertAfterProductUid?: string;
329
+ }
330
+ /**
331
+ * 删除商品后的可选位置保持策略。
332
+ * 预约合并行减量时仍删除最新真实行,再把剩余代表行移动到被删除代表行原位置。
333
+ */
334
+ export interface RemoveProductsFromOrderOptions {
335
+ preserveDisplayPosition?: {
336
+ remainingProductUid: string;
337
+ anchorProductUid: string;
338
+ };
339
+ }
322
340
  /** 更新购物车行:仅传 SKU 时命中同 SKU 第一行;多行同 SKU 须传 unique_identification_number / 选项指纹等 */
323
341
  export interface UpdateOrderProductParams {
324
342
  product_id: number | null;
@@ -685,15 +703,15 @@ export interface OrderModuleAPI {
685
703
  updateTempOrderCustomer: (customer: UpdateTempOrderCustomerInput) => OrderSnapshot['customer'];
686
704
  updateTempOrderBuzzer: (buzzer: string) => string;
687
705
  updateTempOrderContactsInfo: (contactsInfo: Record<string, any> | null) => Record<string, any> | null;
688
- addProductToOrder: (product: Partial<OrderProduct> & OrderProductIdentity, booking?: AddProductBookingInput) => Promise<OrderProduct[]>;
706
+ addProductToOrder: (product: Partial<OrderProduct> & OrderProductIdentity, booking?: AddProductBookingInput, options?: AddProductToOrderOptions) => Promise<OrderProduct[]>;
689
707
  updateOrderProduct: (params: UpdateOrderProductParams) => Promise<OrderProduct[]>;
690
708
  /** 批量更新购物车行,末尾仅触发一次促销重算与 summary 刷新 */
691
709
  updateOrderProducts: (paramsList: UpdateOrderProductParams[]) => Promise<OrderProduct[]>;
692
710
  updateOrderProductQuantity: (params: UpdateOrderProductQuantityParams) => Promise<OrderProduct[]>;
693
711
  updateOrderBooking: (params: UpdateOrderBookingParams) => any[];
694
- removeProductFromOrder: (identity: OrderProductIdentity) => Promise<OrderProduct[]>;
712
+ removeProductFromOrder: (identity: OrderProductIdentity, options?: RemoveProductsFromOrderOptions) => Promise<OrderProduct[]>;
695
713
  /** 批量删除购物车行,末尾仅触发一次促销重算与 summary 刷新 */
696
- removeProductsFromOrder: (identities: OrderProductIdentity[]) => Promise<OrderProduct[]>;
714
+ removeProductsFromOrder: (identities: OrderProductIdentity[], options?: RemoveProductsFromOrderOptions) => Promise<OrderProduct[]>;
697
715
  /** @deprecated no-op;OrderModule 不再负责 tempOrder localStorage 持久化。 */
698
716
  persistTempOrder: () => void;
699
717
  /**
@@ -2,7 +2,7 @@ import { Module, ModuleOptions, PisellCore } from '../../types';
2
2
  import { BaseModule } from '../../modules/BaseModule';
3
3
  import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesUpdateOrderProductQuantityParams, BaseSalesCalculateProductBookingPriceParams, BaseSalesPriceRecalculationContextChange, BaseSalesProductBookingPriceResult, BaseSalesQuotationCustomerScopeInfo, BaseSalesScanCodeResult } from './types';
4
4
  import { OrderModule } from '../../modules/Order';
5
- import type { AddProductBookingInput, LoadSalesDetailParams, OrderPaymentData, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions } from '../../modules/Order/types';
5
+ import type { AddProductBookingInput, AddProductToOrderOptions, LoadSalesDetailParams, OrderPaymentData, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions } from '../../modules/Order/types';
6
6
  import type { SubmitPayloadEnhancer } from '../../modules/Order/utils';
7
7
  import type { Discount } from '../../modules/Discount/types';
8
8
  import { RequestPlugin, WindowPlugin } from '../../plugins';
@@ -315,7 +315,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
315
315
  getQuotationCustomerScopeInfo(): BaseSalesQuotationCustomerScopeInfo;
316
316
  shouldRecalculateProductBookingPricesForContextChange(params: BaseSalesPriceRecalculationContextChange): boolean;
317
317
  calculateProductBookingPrices(paramsList: BaseSalesCalculateProductBookingPriceParams[]): Promise<BaseSalesProductBookingPriceResult[]>;
318
- addProductToOrder(product: Partial<BaseSalesOrderProduct> & BaseSalesOrderProductIdentity, booking?: AddProductBookingInput): Promise<import("../../modules/Order/types").OrderProduct[]>;
318
+ addProductToOrder(product: Partial<BaseSalesOrderProduct> & BaseSalesOrderProductIdentity, booking?: AddProductBookingInput, options?: AddProductToOrderOptions): Promise<import("../../modules/Order/types").OrderProduct[]>;
319
319
  updateOrderProduct(params: UpdateOrderProductParams): Promise<import("../../modules/Order/types").OrderProduct[]>;
320
320
  updateOrderProducts(paramsList: UpdateOrderProductParams[]): Promise<import("../../modules/Order/types").OrderProduct[]>;
321
321
  updateOrderProductQuantity(params: BaseSalesUpdateOrderProductQuantityParams): Promise<import("../../modules/Order/types").OrderProduct[]>;
@@ -331,8 +331,8 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
331
331
  * @example
332
332
  * await baseSales.removeProductsFromOrder([identityA, identityB]);
333
333
  */
334
- removeProductsFromOrder(identities: BaseSalesOrderProductIdentity[]): Promise<import("../../modules/Order/types").OrderProduct[]>;
335
- removeProductFromOrder(identity: BaseSalesOrderProductIdentity): Promise<import("../../modules/Order/types").OrderProduct[]>;
334
+ removeProductsFromOrder(identities: BaseSalesOrderProductIdentity[], options?: RemoveProductsFromOrderOptions): Promise<import("../../modules/Order/types").OrderProduct[]>;
335
+ removeProductFromOrder(identity: BaseSalesOrderProductIdentity, options?: RemoveProductsFromOrderOptions): Promise<import("../../modules/Order/types").OrderProduct[]>;
336
336
  /**
337
337
  * 注入促销评估器到底层 OrderModule。
338
338
  *
@@ -2340,11 +2340,11 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
2340
2340
  });
2341
2341
  });
2342
2342
  }
2343
- async addProductToOrder(product, booking) {
2343
+ async addProductToOrder(product, booking, options) {
2344
2344
  try {
2345
2345
  if (!this.store.order)
2346
2346
  throw new Error("order 模块未初始化");
2347
- const products = await this.store.order.addProductToOrder(product, booking);
2347
+ const products = await this.store.order.addProductToOrder(product, booking, options);
2348
2348
  return products;
2349
2349
  } catch (error) {
2350
2350
  throw error;
@@ -2420,17 +2420,17 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
2420
2420
  * @example
2421
2421
  * await baseSales.removeProductsFromOrder([identityA, identityB]);
2422
2422
  */
2423
- async removeProductsFromOrder(identities) {
2423
+ async removeProductsFromOrder(identities, options) {
2424
2424
  try {
2425
2425
  if (!this.store.order)
2426
2426
  throw new Error("order 模块未初始化");
2427
- return await this.store.order.removeProductsFromOrder(identities);
2427
+ return await this.store.order.removeProductsFromOrder(identities, options);
2428
2428
  } catch (error) {
2429
2429
  throw error;
2430
2430
  }
2431
2431
  }
2432
- async removeProductFromOrder(identity) {
2433
- return this.removeProductsFromOrder([identity]);
2432
+ async removeProductFromOrder(identity, options) {
2433
+ return this.removeProductsFromOrder([identity], options);
2434
2434
  }
2435
2435
  // ─── 促销/赠品 透传(迁移自 booking usePromotion) ────────────────
2436
2436
  /**
@@ -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 | 4 | 5 | 6;
314
+ weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -322,7 +322,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
322
322
  * 获取当前的客户搜索条件
323
323
  * @returns 当前搜索条件
324
324
  */
325
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
325
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
326
326
  /**
327
327
  * 获取客户列表状态(包含滚动加载相关状态)
328
328
  * @returns 客户状态
@@ -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 的客户展示视图。