@pisell/private-materials 6.12.160 → 6.12.162

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 (50) hide show
  1. package/build/lowcode/assets-daily.json +11 -11
  2. package/build/lowcode/assets-dev.json +2 -2
  3. package/build/lowcode/assets-prod.json +11 -11
  4. package/build/lowcode/meta.js +1 -1
  5. package/build/lowcode/preview.js +1 -1
  6. package/build/lowcode/render/default/view.js +18 -18
  7. package/build/lowcode/view.js +18 -18
  8. package/es/components/bigSale/components/ProductList/index.js +30 -19
  9. package/es/components/bigSale/index.js +3 -3
  10. package/es/plus/saleDetail/components/CartItems/Editable/index.js +1 -0
  11. package/es/plus/salesSdk/context/SalesSdkCartContext.js +25 -12
  12. package/es/plus/salesSdk/context/SalesSdkProvider.js +9 -5
  13. package/es/plus/salesSdk/hosts/BookingEditHostRenderer.js +12 -7
  14. package/es/plus/salesSdk/utils/resolvePreviousService.js +28 -0
  15. package/es/plus/salesSdk/utils/runAddProductFlow.js +8 -4
  16. package/es/plus/skuOptionsSelection/components/NormalCard/index.js +18 -12
  17. package/es/plus/skuOptionsSelection/docs/skuOptionsSelection.$tab-dev.md +66 -2
  18. package/es/plus/skuOptionsSelection/types.d.ts +50 -1
  19. package/es/plus/skuOptionsSelection/utils/normalizers.js +17 -0
  20. package/es/plus/skuOptionsSelection/utils/transformOptionGroup.js +17 -7
  21. package/es/plus/skuOptionsSelection/utils/transformSelectorValueToValue.js +89 -15
  22. package/es/plus/skuOptionsSelection/utils/transformValueToSelectorValue.js +31 -19
  23. package/es/pro/Selector/Selector.js +11 -6
  24. package/es/pro/Selector/hooks/useSelectionController.js +54 -61
  25. package/es/pro/Selector/locales.js +10 -0
  26. package/es/pro/Selector/types.d.ts +5 -0
  27. package/es/pro/skuDetailModal/index.js +4 -4
  28. package/es/pro/skuDetailModal/types.d.ts +1 -0
  29. package/lib/components/bigSale/components/ProductList/index.js +30 -19
  30. package/lib/components/bigSale/index.js +3 -3
  31. package/lib/plus/saleDetail/components/CartItems/Editable/index.js +1 -0
  32. package/lib/plus/salesSdk/context/SalesSdkCartContext.js +25 -12
  33. package/lib/plus/salesSdk/context/SalesSdkProvider.js +9 -5
  34. package/lib/plus/salesSdk/hosts/BookingEditHostRenderer.js +12 -7
  35. package/lib/plus/salesSdk/utils/resolvePreviousService.js +30 -0
  36. package/lib/plus/salesSdk/utils/runAddProductFlow.js +8 -4
  37. package/lib/plus/skuOptionsSelection/components/NormalCard/index.js +18 -12
  38. package/lib/plus/skuOptionsSelection/docs/skuOptionsSelection.$tab-dev.md +66 -2
  39. package/lib/plus/skuOptionsSelection/types.d.ts +50 -1
  40. package/lib/plus/skuOptionsSelection/utils/normalizers.js +19 -0
  41. package/lib/plus/skuOptionsSelection/utils/transformOptionGroup.js +17 -7
  42. package/lib/plus/skuOptionsSelection/utils/transformSelectorValueToValue.js +89 -15
  43. package/lib/plus/skuOptionsSelection/utils/transformValueToSelectorValue.js +31 -19
  44. package/lib/pro/Selector/Selector.js +11 -6
  45. package/lib/pro/Selector/hooks/useSelectionController.js +54 -61
  46. package/lib/pro/Selector/locales.js +10 -0
  47. package/lib/pro/Selector/types.d.ts +5 -0
  48. package/lib/pro/skuDetailModal/index.js +4 -4
  49. package/lib/pro/skuDetailModal/types.d.ts +1 -0
  50. package/package.json +3 -3
@@ -29,6 +29,7 @@ const require_bookingDate = require("../utils/bookingDate.js");
29
29
  const require_assignHolderToCartLine = require("../utils/assignHolderToCartLine.js");
30
30
  const require_holderSubmitValidation = require("../utils/holderSubmitValidation.js");
31
31
  const require_removeOrderProducts = require("../utils/removeOrderProducts.js");
32
+ const require_resolvePreviousService = require("../utils/resolvePreviousService.js");
32
33
  const require_locales = require("../../../components/ticketBooking/locales.js");
33
34
  const require_editCartLine = require("../utils/editCartLine.js");
34
35
  const require_syncBookingLineQuantityByRows = require("../utils/syncBookingLineQuantityByRows.js");
@@ -796,6 +797,7 @@ const SalesSdkCartProvider = ({ children, shouldMergeProductLines, mergeBookingL
796
797
  const customerId = require_buildBookingEditDrawerState.resolveAddFlowCustomerId(liveTempOrder, void 0, bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getOrd2 = bookingTicket.getOrderCustomerSnapshot) === null || _bookingTicket$getOrd2 === void 0 || (_bookingTicket$getOrd2 = _bookingTicket$getOrd2.call(bookingTicket)) === null || _bookingTicket$getOrd2 === void 0 ? void 0 : _bookingTicket$getOrd2.id);
797
798
  return {
798
799
  bookingConfig: (_bookingTicket$getBoo5 = bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getBoo6 = bookingTicket.getBookingConfig) === null || _bookingTicket$getBoo6 === void 0 ? void 0 : _bookingTicket$getBoo6.call(bookingTicket)) !== null && _bookingTicket$getBoo5 !== void 0 ? _bookingTicket$getBoo5 : null,
800
+ previousService: require_resolvePreviousService.resolvePreviousService(liveTempOrder),
799
801
  customerId,
800
802
  tempOrder: liveTempOrder,
801
803
  isFranchisee: Boolean(bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getOth = bookingTicket.getOtherParams) === null || _bookingTicket$getOth === void 0 || (_bookingTicket$getOth = _bookingTicket$getOth.call(bookingTicket)) === null || _bookingTicket$getOth === void 0 ? void 0 : _bookingTicket$getOth.isFranchisee),
@@ -858,7 +860,7 @@ const SalesSdkCartProvider = ({ children, shouldMergeProductLines, mergeBookingL
858
860
  });
859
861
  const addProductToOrderFromCacheImpl = (0, ahooks.useMemoizedFn)(function() {
860
862
  var _ref9 = require_asyncToGenerator._asyncToGenerator(function* (item, cacheItem, options) {
861
- var _flowCtx$date, _ref8, _cacheItemForTransfor, _cacheItemForTransfor2;
863
+ var _flowCtx$date, _flowCtx$bookingConfi, _ref8, _cacheItemForTransfor, _cacheItemForTransfor2;
862
864
  if (!bookingTicket) throw new Error("[SalesSdk] Cart: bookingTicket 未初始化");
863
865
  if (typeof bookingTicket.transformDetailToProductAndBooking !== "function") throw new Error("[SalesSdk] Cart: bookingTicket.transformDetailToProductAndBooking 不可用");
864
866
  const flowCtx = getAddFlowContext();
@@ -868,7 +870,9 @@ const SalesSdkCartProvider = ({ children, shouldMergeProductLines, mergeBookingL
868
870
  cacheItem: cacheItemForTransform,
869
871
  options: {
870
872
  quantity: options === null || options === void 0 ? void 0 : options.quantity,
871
- date: (_flowCtx$date = flowCtx.date) !== null && _flowCtx$date !== void 0 ? _flowCtx$date : void 0
873
+ date: (_flowCtx$date = flowCtx.date) !== null && _flowCtx$date !== void 0 ? _flowCtx$date : void 0,
874
+ bookingConfig: (_flowCtx$bookingConfi = flowCtx.bookingConfig) !== null && _flowCtx$bookingConfi !== void 0 ? _flowCtx$bookingConfi : void 0,
875
+ previousService: flowCtx.previousService
872
876
  }
873
877
  });
874
878
  orderLine.note = (_ref8 = (_cacheItemForTransfor = cacheItemForTransform === null || cacheItemForTransform === void 0 || (_cacheItemForTransfor2 = cacheItemForTransform._extend) === null || _cacheItemForTransfor2 === void 0 ? void 0 : _cacheItemForTransfor2.note) !== null && _cacheItemForTransfor !== void 0 ? _cacheItemForTransfor : orderLine.note) !== null && _ref8 !== void 0 ? _ref8 : "";
@@ -920,7 +924,7 @@ const SalesSdkCartProvider = ({ children, shouldMergeProductLines, mergeBookingL
920
924
  */
921
925
  const addProduct = (0, ahooks.useMemoizedFn)(function() {
922
926
  var _ref13 = require_asyncToGenerator._asyncToGenerator(function* (product, options) {
923
- var _flowCtx$date2;
927
+ var _flowCtx$date2, _flowCtx$bookingConfi2;
924
928
  if (!bookingTicket) throw new Error("[SalesSdk] Cart: bookingTicket 未初始化");
925
929
  if (typeof bookingTicket.decideAddProduct !== "function") throw new Error("[SalesSdk] Cart: bookingTicket.decideAddProduct 不可用,请升级 pisellos");
926
930
  const flowCtx = getAddFlowContext();
@@ -969,7 +973,9 @@ const SalesSdkCartProvider = ({ children, shouldMergeProductLines, mergeBookingL
969
973
  type: (options === null || options === void 0 ? void 0 : options.type) || "select",
970
974
  quantity: options === null || options === void 0 ? void 0 : options.quantity,
971
975
  date: (_flowCtx$date2 = flowCtx.date) !== null && _flowCtx$date2 !== void 0 ? _flowCtx$date2 : void 0,
972
- customerId: flowCtx.customerId
976
+ customerId: flowCtx.customerId,
977
+ bookingConfig: (_flowCtx$bookingConfi2 = flowCtx.bookingConfig) !== null && _flowCtx$bookingConfi2 !== void 0 ? _flowCtx$bookingConfi2 : void 0,
978
+ previousService: flowCtx.previousService
973
979
  });
974
980
  if (decision.action === "reloadCatalog") {
975
981
  yield reloadProductCatalogForStaleSession();
@@ -989,14 +995,16 @@ const SalesSdkCartProvider = ({ children, shouldMergeProductLines, mergeBookingL
989
995
  };
990
996
  }
991
997
  if (decision.action === "requiresDetail") {
992
- var _decision$payload, _bookingTicket$buildR, _flowCtx$date4;
998
+ var _decision$payload, _bookingTicket$buildR, _flowCtx$date4, _flowCtx$bookingConfi3;
993
999
  return {
994
1000
  status: "requiresDetail",
995
1001
  payload: (_decision$payload = decision.payload) !== null && _decision$payload !== void 0 ? _decision$payload : (_bookingTicket$buildR = bookingTicket.buildRequiresDetailPayload) === null || _bookingTicket$buildR === void 0 ? void 0 : _bookingTicket$buildR.call(bookingTicket, product, {
996
1002
  type: (options === null || options === void 0 ? void 0 : options.type) || "select",
997
1003
  quantity: options === null || options === void 0 ? void 0 : options.quantity,
998
1004
  date: (_flowCtx$date4 = flowCtx.date) !== null && _flowCtx$date4 !== void 0 ? _flowCtx$date4 : void 0,
999
- customerId: flowCtx.customerId
1005
+ customerId: flowCtx.customerId,
1006
+ bookingConfig: (_flowCtx$bookingConfi3 = flowCtx.bookingConfig) !== null && _flowCtx$bookingConfi3 !== void 0 ? _flowCtx$bookingConfi3 : void 0,
1007
+ previousService: flowCtx.previousService
1000
1008
  })
1001
1009
  };
1002
1010
  }
@@ -1022,7 +1030,7 @@ const SalesSdkCartProvider = ({ children, shouldMergeProductLines, mergeBookingL
1022
1030
  */
1023
1031
  const confirmDetail = (0, ahooks.useMemoizedFn)(function() {
1024
1032
  var _ref15 = require_asyncToGenerator._asyncToGenerator(function* (input) {
1025
- var _flowCtx$date7, _input$options, _input$options3;
1033
+ var _flowCtx$date7, _flowCtx$bookingConfi4, _input$options, _input$options3;
1026
1034
  if (!bookingTicket) throw new Error("[SalesSdk] Cart: bookingTicket 未初始化");
1027
1035
  if (typeof bookingTicket.transformDetailToProductAndBooking !== "function") throw new Error("[SalesSdk] Cart: bookingTicket.transformDetailToProductAndBooking 不可用");
1028
1036
  const confirmQuantity = require_resolveConfirmDetailQuantity.resolveConfirmDetailQuantity(input);
@@ -1033,7 +1041,9 @@ const SalesSdkCartProvider = ({ children, shouldMergeProductLines, mergeBookingL
1033
1041
  options: {
1034
1042
  quantity: confirmQuantity,
1035
1043
  date: (_flowCtx$date7 = flowCtx.date) !== null && _flowCtx$date7 !== void 0 ? _flowCtx$date7 : void 0,
1036
- customerId: flowCtx.customerId
1044
+ customerId: flowCtx.customerId,
1045
+ bookingConfig: (_flowCtx$bookingConfi4 = flowCtx.bookingConfig) !== null && _flowCtx$bookingConfi4 !== void 0 ? _flowCtx$bookingConfi4 : void 0,
1046
+ previousService: flowCtx.previousService
1037
1047
  }
1038
1048
  });
1039
1049
  const catalogItem = input.item;
@@ -1041,12 +1051,13 @@ const SalesSdkCartProvider = ({ children, shouldMergeProductLines, mergeBookingL
1041
1051
  if ((_input$options = input.options) === null || _input$options === void 0 ? void 0 : _input$options.multiDayRange) cacheItem = require_patchCacheItemDateRange.patchCacheItemDateRange(cacheItem, input.options.multiDayRange);
1042
1052
  else cacheItem = require_patchCacheItemDateRange.applyDefaultMultiDayRangeIfNeeded(cacheItem, catalogItem, flowCtx.date);
1043
1053
  if (typeof bookingTicket.decideAfterDetail === "function") {
1044
- var _flowCtx$date8, _flowCtx$bookingConfi, _input$options2;
1054
+ var _flowCtx$date8, _flowCtx$bookingConfi5, _input$options2;
1045
1055
  const decision = bookingTicket.decideAfterDetail(cacheItem, {
1046
1056
  quantity: confirmQuantity,
1047
1057
  customerId: flowCtx.customerId,
1048
1058
  date: (_flowCtx$date8 = flowCtx.date) !== null && _flowCtx$date8 !== void 0 ? _flowCtx$date8 : void 0,
1049
- bookingConfig: (_flowCtx$bookingConfi = flowCtx.bookingConfig) !== null && _flowCtx$bookingConfi !== void 0 ? _flowCtx$bookingConfi : void 0
1059
+ bookingConfig: (_flowCtx$bookingConfi5 = flowCtx.bookingConfig) !== null && _flowCtx$bookingConfi5 !== void 0 ? _flowCtx$bookingConfi5 : void 0,
1060
+ previousService: flowCtx.previousService
1050
1061
  });
1051
1062
  if (decision.action === "requiresBookingEdit") {
1052
1063
  var _decision$payload5, _ref14, _flowCtx$date9, _decision$payload6, _flowCtx$customerId2, _decision$payload7;
@@ -1165,13 +1176,15 @@ const SalesSdkCartProvider = ({ children, shouldMergeProductLines, mergeBookingL
1165
1176
  };
1166
1177
  }(),
1167
1178
  decideAddProduct: (product, opts) => {
1168
- var _flowCtx$date11;
1179
+ var _flowCtx$date11, _flowCtx$bookingConfi6;
1169
1180
  const ticket = bookingTicketRef.current;
1170
1181
  if (!ticket || typeof ticket.decideAddProduct !== "function") return { action: "requiresDetail" };
1171
1182
  const flowCtx = getAddFlowContextRef.current();
1172
1183
  return ticket.decideAddProduct(product, require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, opts), {}, {
1173
1184
  date: (_flowCtx$date11 = flowCtx.date) !== null && _flowCtx$date11 !== void 0 ? _flowCtx$date11 : void 0,
1174
- customerId: flowCtx.customerId
1185
+ customerId: flowCtx.customerId,
1186
+ bookingConfig: (_flowCtx$bookingConfi6 = flowCtx.bookingConfig) !== null && _flowCtx$bookingConfi6 !== void 0 ? _flowCtx$bookingConfi6 : void 0,
1187
+ previousService: flowCtx.previousService
1175
1188
  }));
1176
1189
  },
1177
1190
  runAddProductFlow: (product, opts) => runFlowRef.current(product, opts),
@@ -151,7 +151,7 @@ function runAfterNextPaint(task) {
151
151
  * - 新建态:按 OS persist 开关走 createNew 或 restore → initBookingContext
152
152
  * 须位于 SalesSdkSummaryProvider 内,以便 summaryProviderRef 已通过 useImperativeHandle 注入。
153
153
  */
154
- function SalesSdkBootstrap({ solution, autoRestoreOnInit, autoBootstrap, autoInitBookingContext, orderId, preloadedSalesDetail, initBookingContext, prepareModule, prepareCatalog, catalogKey, lifecycleOwner }) {
154
+ function SalesSdkBootstrap({ autoRestoreOnInit, autoBootstrap, autoInitBookingContext, orderId, preloadedSalesDetail, initBookingContext, prepareModule, prepareCatalog, catalogKey, lifecycleOwner }) {
155
155
  const sales = (0, react.useContext)(require_SalesSdkContext.SalesSdkContext);
156
156
  const cart = require_useSalesSdkCart.useSalesSdkCart();
157
157
  (0, react.useEffect)(() => {
@@ -185,7 +185,7 @@ function SalesSdkBootstrap({ solution, autoRestoreOnInit, autoBootstrap, autoIni
185
185
  }
186
186
  }
187
187
  }
188
- if (cancelled || !autoInitBookingContext || solution === "unifiedBookingSales") return;
188
+ if (cancelled || !autoInitBookingContext) return;
189
189
  const bookingIds = require_buildDefaultLoadProductsParams.collectBookingIdsFromTempOrder((_sales$bookingTicket$2 = (_sales$bookingTicket2 = sales.bookingTicket) === null || _sales$bookingTicket2 === void 0 || (_sales$bookingTicket3 = _sales$bookingTicket2.getTempOrder) === null || _sales$bookingTicket3 === void 0 ? void 0 : _sales$bookingTicket3.call(_sales$bookingTicket2)) !== null && _sales$bookingTicket$2 !== void 0 ? _sales$bookingTicket$2 : null);
190
190
  yield initBookingContext(bookingIds.length ? bookingIds : void 0, { loadResources: !(autoBootstrap && orderId) });
191
191
  } catch (e) {
@@ -212,7 +212,6 @@ function SalesSdkBootstrap({ solution, autoRestoreOnInit, autoBootstrap, autoIni
212
212
  autoRestoreOnInit,
213
213
  autoBootstrap,
214
214
  autoInitBookingContext,
215
- solution,
216
215
  orderId,
217
216
  preloadedSalesDetail,
218
217
  initBookingContext,
@@ -651,7 +650,13 @@ const SalesSdkProvider = ({ osKey, solution = "bookingTicket", moduleAccess = "e
651
650
  */
652
651
  const initBookingContext = (0, ahooks.useMemoizedFn)(function() {
653
652
  var _ref2 = require_asyncToGenerator._asyncToGenerator(function* (bookingIds, options) {
654
- if (!(bookingTicket === null || bookingTicket === void 0 ? void 0 : bookingTicket.initBookingContext)) return;
653
+ if (!bookingTicket) return;
654
+ if (String((otherParams === null || otherParams === void 0 ? void 0 : otherParams.platform) || "").trim().toLowerCase() === "h5") {
655
+ var _bookingTicket$loadBo;
656
+ yield (_bookingTicket$loadBo = bookingTicket.loadBookingConfig) === null || _bookingTicket$loadBo === void 0 ? void 0 : _bookingTicket$loadBo.call(bookingTicket, bookingConfigParams);
657
+ return;
658
+ }
659
+ if (!bookingTicket.initBookingContext) return;
655
660
  yield bookingTicket.initBookingContext(require_buildDefaultLoadProductsParams.buildInitBookingContextParams(bookingConfigParams, {
656
661
  bookingIds,
657
662
  loadResources: options === null || options === void 0 ? void 0 : options.loadResources
@@ -1343,7 +1348,6 @@ const SalesSdkProvider = ({ osKey, solution = "bookingTicket", moduleAccess = "e
1343
1348
  onPromotionScanComplete: handlePromotionScanComplete,
1344
1349
  promotionScanSuccessMessageKey: promotionItemIncreaseMessageKey ? void 0 : promotionScanSuccessMessageKey
1345
1350
  }), /* @__PURE__ */ react.default.createElement(SalesSdkBootstrap, {
1346
- solution,
1347
1351
  autoRestoreOnInit,
1348
1352
  autoBootstrap,
1349
1353
  autoInitBookingContext,
@@ -6,6 +6,7 @@ const require_buildDefaultLoadProductsParams = require("../utils/buildDefaultLoa
6
6
  const require_buildBookingEditDrawerState = require("../bookingEditService/buildBookingEditDrawerState.js");
7
7
  const require_resolveIsMultiDayProduct = require("../utils/resolveIsMultiDayProduct.js");
8
8
  const require_multiDayPriceCache = require("../utils/multiDayPriceCache.js");
9
+ const require_resolvePreviousService = require("../utils/resolvePreviousService.js");
9
10
  const require_prepareCacheItemForBookingEdit = require("../bookingEditService/prepareCacheItemForBookingEdit.js");
10
11
  const require_useSalesSdk = require("../hooks/useSalesSdk.js");
11
12
  const require_useSyncExternalStoreCompat = require("../hooks/useSyncExternalStoreCompat.js");
@@ -20,11 +21,15 @@ let _pisell_utils = require("@pisell/utils");
20
21
  /**
21
22
  * 将 Host payload 的 cacheItem 补齐展示字段并写入 state。
22
23
  */
23
- function normalizeCacheItemForDrawer(rawItem, bookingTicket, forceOpen) {
24
+ function normalizeCacheItemForDrawer(rawItem, bookingTicket, tempOrder, forceOpen) {
24
25
  let item = rawItem;
25
26
  if (require_multiDayPriceCache.isMultiDayQuotationExpanded(item)) item = require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, item), {}, { new: 0 });
26
27
  if (typeof bookingTicket.getProductExtend === "function") try {
27
- item = bookingTicket.getProductExtend(item);
28
+ var _bookingTicket$getBoo, _bookingTicket$getBoo2;
29
+ item = bookingTicket.getProductExtend(item, {
30
+ bookingConfig: (_bookingTicket$getBoo = (_bookingTicket$getBoo2 = bookingTicket.getBookingConfig) === null || _bookingTicket$getBoo2 === void 0 ? void 0 : _bookingTicket$getBoo2.call(bookingTicket)) !== null && _bookingTicket$getBoo !== void 0 ? _bookingTicket$getBoo : void 0,
31
+ previousService: require_resolvePreviousService.resolvePreviousService(tempOrder)
32
+ });
28
33
  } catch (e) {
29
34
  console.warn("[SalesSdk] getProductExtend 失败,使用原始 cacheItem", e);
30
35
  }
@@ -81,7 +86,7 @@ const BookingEditHostRenderer = () => {
81
86
  var _ref = require_asyncToGenerator._asyncToGenerator(function* () {
82
87
  yield ensureBookingContextForDrawer(bookingTicket, payload, tempOrder, bookingConfigParams);
83
88
  if (cancelled) return;
84
- const item = normalizeCacheItemForDrawer(payload.cacheItem, bookingTicket, payload.forceOpen);
89
+ const item = normalizeCacheItemForDrawer(payload.cacheItem, bookingTicket, tempOrder, payload.forceOpen);
85
90
  if (item.autoClose && !payload.forceOpen) {
86
91
  bridge.complete(item);
87
92
  return;
@@ -93,7 +98,7 @@ const BookingEditHostRenderer = () => {
93
98
  };
94
99
  })()().catch((err) => {
95
100
  console.warn("[SalesSdk] openBookingEdit 初始化资源上下文失败", err);
96
- if (!cancelled) setCacheItem(normalizeCacheItemForDrawer(payload.cacheItem, bookingTicket, payload.forceOpen));
101
+ if (!cancelled) setCacheItem(normalizeCacheItemForDrawer(payload.cacheItem, bookingTicket, tempOrder, payload.forceOpen));
97
102
  });
98
103
  return () => {
99
104
  cancelled = true;
@@ -179,10 +184,10 @@ const BookingEditHostRenderer = () => {
179
184
  cacheItem === null || cacheItem === void 0 || (_cacheItem$_data = cacheItem._data) === null || _cacheItem$_data === void 0 || (_cacheItem$_data = _cacheItem$_data.resources) === null || _cacheItem$_data === void 0 ? void 0 : _cacheItem$_data.length
180
185
  ]);
181
186
  const bookingState = (0, react.useMemo)(() => {
182
- var _bookingTicket$getBoo, _bookingTicket$getBoo2, _ref3, _payload$date2, _bookingTicket$getBoo3, _bookingTicket$getTem3, _bookingTicket$getTem4, _bookingTicket$getOrd, _bookingTicket$getOth;
187
+ var _bookingTicket$getBoo3, _bookingTicket$getBoo4, _ref3, _payload$date2, _bookingTicket$getBoo5, _bookingTicket$getTem3, _bookingTicket$getTem4, _bookingTicket$getOrd, _bookingTicket$getOth;
183
188
  if (!cacheItem) return null;
184
- const bookingConfig = (_bookingTicket$getBoo = bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getBoo2 = bookingTicket.getBookingConfig) === null || _bookingTicket$getBoo2 === void 0 ? void 0 : _bookingTicket$getBoo2.call(bookingTicket)) !== null && _bookingTicket$getBoo !== void 0 ? _bookingTicket$getBoo : null;
185
- const date = (_ref3 = (_payload$date2 = payload === null || payload === void 0 ? void 0 : payload.date) !== null && _payload$date2 !== void 0 ? _payload$date2 : bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getBoo3 = bookingTicket.getBookingDate) === null || _bookingTicket$getBoo3 === void 0 ? void 0 : _bookingTicket$getBoo3.call(bookingTicket)) !== null && _ref3 !== void 0 ? _ref3 : (0, dayjs.default)().format("YYYY-MM-DD");
189
+ const bookingConfig = (_bookingTicket$getBoo3 = bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getBoo4 = bookingTicket.getBookingConfig) === null || _bookingTicket$getBoo4 === void 0 ? void 0 : _bookingTicket$getBoo4.call(bookingTicket)) !== null && _bookingTicket$getBoo3 !== void 0 ? _bookingTicket$getBoo3 : null;
190
+ const date = (_ref3 = (_payload$date2 = payload === null || payload === void 0 ? void 0 : payload.date) !== null && _payload$date2 !== void 0 ? _payload$date2 : bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getBoo5 = bookingTicket.getBookingDate) === null || _bookingTicket$getBoo5 === void 0 ? void 0 : _bookingTicket$getBoo5.call(bookingTicket)) !== null && _ref3 !== void 0 ? _ref3 : (0, dayjs.default)().format("YYYY-MM-DD");
186
191
  const liveTempOrder = (_bookingTicket$getTem3 = bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getTem4 = bookingTicket.getTempOrder) === null || _bookingTicket$getTem4 === void 0 ? void 0 : _bookingTicket$getTem4.call(bookingTicket)) !== null && _bookingTicket$getTem3 !== void 0 ? _bookingTicket$getTem3 : tempOrder;
187
192
  return require_buildBookingEditDrawerState.buildBookingEditDrawerState({
188
193
  cacheItem,
@@ -0,0 +1,30 @@
1
+ const require_runtime = require("../../../_virtual/_rolldown/runtime.js");
2
+ let dayjs = require("dayjs");
3
+ dayjs = require_runtime.__toESM(dayjs);
4
+ //#region src/plus/salesSdk/utils/resolvePreviousService.ts
5
+ /**
6
+ * 取得下一预约计算开始时间时所需的“上一服务”。
7
+ *
8
+ * 对齐 info2:它会过滤自定义/普通商品后,通过 getLastServer 取 service.value[0]。
9
+ * SalesSdk 的 tempOrder.bookings 按加入顺序追加,因此从后向前取最后一条
10
+ * 时间完整的商品预约,转换为 OS BookingCalcContext 所需结构。
11
+ * `parent_id === 0` 是订单级 root booking,不对应商品行,需要跳过;
12
+ * 新建本地预约的 parent_id 可能尚未生成(null/undefined),仍属于有效候选。
13
+ */
14
+ function resolvePreviousService(tempOrder) {
15
+ const bookings = Array.isArray(tempOrder === null || tempOrder === void 0 ? void 0 : tempOrder.bookings) ? tempOrder.bookings : [];
16
+ for (let index = bookings.length - 1; index >= 0; index -= 1) {
17
+ const booking = bookings[index];
18
+ if ((booking === null || booking === void 0 ? void 0 : booking.parent_id) != null && Number(booking.parent_id) === 0) continue;
19
+ if (!(booking === null || booking === void 0 ? void 0 : booking.start_date) || !(booking === null || booking === void 0 ? void 0 : booking.start_time) || !(booking === null || booking === void 0 ? void 0 : booking.end_date) || !(booking === null || booking === void 0 ? void 0 : booking.end_time)) continue;
20
+ const startDate = (0, dayjs.default)(`${booking.start_date} ${booking.start_time}`);
21
+ const endDate = (0, dayjs.default)(`${booking.end_date} ${booking.end_time}`);
22
+ if (!startDate.isValid() || !endDate.isValid()) continue;
23
+ return { _extend: {
24
+ startDate,
25
+ endDate
26
+ } };
27
+ }
28
+ }
29
+ //#endregion
30
+ exports.resolvePreviousService = resolvePreviousService;
@@ -154,10 +154,14 @@ function _runAddProductFlow() {
154
154
  initialHolderIds: (_flowOptions$initialH = flowOptions.initialHolderIds) !== null && _flowOptions$initialH !== void 0 ? _flowOptions$initialH : result.payload.initialHolderIds
155
155
  }));
156
156
  if (!detailResult) return { status: "cancelled" };
157
- if (detailResult._committedProducts) return {
158
- status: "added",
159
- products: detailResult._committedProducts
160
- };
157
+ if (detailResult._committedProducts) {
158
+ var _flowOptions$onBookin2;
159
+ yield (_flowOptions$onBookin2 = flowOptions.onBookingSelectionCommitted) === null || _flowOptions$onBookin2 === void 0 ? void 0 : _flowOptions$onBookin2.call(flowOptions);
160
+ return {
161
+ status: "added",
162
+ products: detailResult._committedProducts
163
+ };
164
+ }
161
165
  const catalog = (_result$payload$produ = (_result$payload = result.payload) === null || _result$payload === void 0 ? void 0 : _result$payload.productData) !== null && _result$payload$produ !== void 0 ? _result$payload$produ : product;
162
166
  const detailExtend = (_detailResult$detail = detailResult.detail) === null || _detailResult$detail === void 0 ? void 0 : _detailResult$detail._extend;
163
167
  const hasFlowSelectedMultiDayRange = require_resolveIsMultiDayProduct.resolveIsMultiDayProduct(detailResult.detail, catalog, product) && (detailExtend === null || detailExtend === void 0 ? void 0 : detailExtend.start_date) && (detailExtend === null || detailExtend === void 0 ? void 0 : detailExtend.end_date);
@@ -9,7 +9,7 @@ let decimal_js = require("decimal.js");
9
9
  decimal_js = require_runtime.__toESM(decimal_js);
10
10
  //#region src/plus/skuOptionsSelection/components/NormalCard/index.tsx
11
11
  const NormalCard = (props) => {
12
- var _props$dataSource;
12
+ var _props$dataSource2;
13
13
  const { _key: uniqueKey, ruleConfig, _original, disabled, selected } = (props === null || props === void 0 ? void 0 : props.dataSource) || {};
14
14
  const { cover, title, name, product_subtitle, price, price_type, add_price } = _original || {};
15
15
  const symbol = require_useStore.default((s) => s.symbol);
@@ -25,20 +25,25 @@ const NormalCard = (props) => {
25
25
  };
26
26
  const renderNumberSelector = () => {
27
27
  if (!(props === null || props === void 0 ? void 0 : props.numberSelector) || typeof (props === null || props === void 0 ? void 0 : props.numberSelector) !== "object") return null;
28
- return react.default.cloneElement(props === null || props === void 0 ? void 0 : props.numberSelector, { onChange: (v) => {
29
- var _props$actions;
28
+ return react.default.cloneElement(props === null || props === void 0 ? void 0 : props.numberSelector, { onChange: (v, meta) => {
29
+ var _props$dataSource, _props$actions;
30
+ const itemMin = Math.max(1, Number((ruleConfig === null || ruleConfig === void 0 ? void 0 : ruleConfig.min) || 0));
31
+ const currentQuantity = Number((props === null || props === void 0 || (_props$dataSource = props.dataSource) === null || _props$dataSource === void 0 ? void 0 : _props$dataSource.quantity) || 0);
32
+ let nextQuantity = v;
33
+ if ((meta === null || meta === void 0 ? void 0 : meta.action) === "increase" && currentQuantity <= 0) nextQuantity = itemMin;
34
+ else if ((meta === null || meta === void 0 ? void 0 : meta.action) === "decrease" && itemMin > 1 && currentQuantity === itemMin && v < itemMin) nextQuantity = 0;
30
35
  const _price = add_price !== void 0 && add_price !== null ? add_price : price;
31
36
  const priceType = price_type === "markdown" ? -1 : 1;
32
- const totalPrice = new decimal_js.default(_price).times(new decimal_js.default(v)).times(priceType).toNumber();
37
+ const totalPrice = new decimal_js.default(_price).times(new decimal_js.default(nextQuantity)).times(priceType).toNumber();
33
38
  const newOriginal = require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, _original), {}, {
34
- quantity: v,
35
- num: v,
39
+ quantity: nextQuantity,
40
+ num: nextQuantity,
36
41
  price: _price,
37
42
  original_price: _price,
38
43
  original_total: _price
39
44
  });
40
45
  props === null || props === void 0 || (_props$actions = props.actions) === null || _props$actions === void 0 || _props$actions.update(uniqueKey, {
41
- quantity: v,
46
+ quantity: nextQuantity,
42
47
  data: newOriginal,
43
48
  totalPrice
44
49
  });
@@ -65,17 +70,18 @@ const NormalCard = (props) => {
65
70
  var _props$actions3;
66
71
  const _price = add_price !== void 0 && add_price !== null ? add_price : price;
67
72
  const priceType = price_type === "markdown" ? -1 : 1;
73
+ const initialQuantity = Math.max(1, Number((ruleConfig === null || ruleConfig === void 0 ? void 0 : ruleConfig.min) || 0));
68
74
  const newOriginal = require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, _original), {}, {
69
- quantity: 1,
70
- num: 1,
75
+ quantity: initialQuantity,
76
+ num: initialQuantity,
71
77
  price: _price,
72
78
  original_price: _price,
73
79
  original_total: _price
74
80
  });
75
81
  props === null || props === void 0 || (_props$actions3 = props.actions) === null || _props$actions3 === void 0 || _props$actions3.update(uniqueKey, {
76
- quantity: 1,
82
+ quantity: initialQuantity,
77
83
  data: newOriginal,
78
- totalPrice: new decimal_js.default(_price).times(priceType).toNumber()
84
+ totalPrice: new decimal_js.default(_price).times(initialQuantity).times(priceType).toNumber()
79
85
  });
80
86
  }
81
87
  };
@@ -102,7 +108,7 @@ const NormalCard = (props) => {
102
108
  } }))),
103
109
  onClick: handleChange,
104
110
  skuCardConfig,
105
- skuDisabled: (props === null || props === void 0 || (_props$dataSource = props.dataSource) === null || _props$dataSource === void 0 || (_props$dataSource = _props$dataSource._extra) === null || _props$dataSource === void 0 ? void 0 : _props$dataSource.disabled) === true
111
+ skuDisabled: (props === null || props === void 0 || (_props$dataSource2 = props.dataSource) === null || _props$dataSource2 === void 0 || (_props$dataSource2 = _props$dataSource2._extra) === null || _props$dataSource2 === void 0 ? void 0 : _props$dataSource2.disabled) === true
106
112
  });
107
113
  };
108
114
  //#endregion
@@ -15,7 +15,7 @@ category: plus
15
15
  ## 2. 版本
16
16
 
17
17
  **当前版本**: `1.0.0`
18
- **最后更新**: 2025-11-19
18
+ **最后更新**: 2026-08-12
19
19
 
20
20
  ## 3. 相关文档
21
21
 
@@ -51,6 +51,10 @@ SKUOptionsSelection
51
51
 
52
52
  ```typescript
53
53
  export interface DataSource {
54
+ /** 商品id */
55
+ id?: number;
56
+ /** 生产编码 */
57
+ production_code?: string;
54
58
  /** 单规格组数据 */
55
59
  option_group?: Array<OptionGroupItem>;
56
60
  /** 组合规格组装后的数据 */
@@ -58,7 +62,17 @@ export interface DataSource {
58
62
  /** 组合规格组数据 */
59
63
  variant_group?: Array<VariantGroupItem>;
60
64
  /** 套餐商品组数据 */
61
- bundle_group?: Array<BundleItem>;
65
+ bundle_group?: Array<BundleGroupItem>;
66
+ }
67
+
68
+ export interface OptionGroupMetadata {
69
+ advanced_settings_enabled?: 0 | 1;
70
+ option_types_config?: {
71
+ min?: number;
72
+ max?: number;
73
+ [key: string]: unknown;
74
+ };
75
+ [key: string]: unknown;
62
76
  }
63
77
 
64
78
  /**
@@ -88,6 +102,8 @@ export interface OptionGroupItem {
88
102
  max_quantity?: number;
89
103
  /** 最小选择数量 */
90
104
  min_quantity?: number;
105
+ /** 高级设置元数据 */
106
+ metadata?: OptionGroupMetadata;
91
107
  /** 单规格组名称 */
92
108
  name?: string;
93
109
  /** 单规格组下规格数据 */
@@ -133,6 +149,8 @@ export interface OptionItem {
133
149
  is_enabled?: 0 | 1;
134
150
  /** 最大选择数量 */
135
151
  max_quantity?: number;
152
+ /** 最小选择数量 */
153
+ min_quantity?: number;
136
154
  /** 规格名称 */
137
155
  name?: string;
138
156
  /** 规格组id */
@@ -141,6 +159,8 @@ export interface OptionItem {
141
159
  original_price?: string;
142
160
  /** 商品id */
143
161
  product_id?: number;
162
+ /** 生产编码 */
163
+ production_code?: string;
144
164
  /** 店铺id */
145
165
  shop_id?: number;
146
166
  /** 排序 */
@@ -268,6 +288,8 @@ export interface VariantProductItem {
268
288
  price?: string;
269
289
  /** 商品id */
270
290
  product_id?: number;
291
+ /** 生产编码 */
292
+ production_code?: string;
271
293
  /** 折扣类型 */
272
294
  rebate_type?: string;
273
295
  /** 折扣值 */
@@ -350,6 +372,8 @@ export interface BundleItem {
350
372
  price_type_ext?: '' | 'product_price';
351
373
  /** 商品id */
352
374
  product_id?: number;
375
+ /** 生产编码 */
376
+ production_code?: string;
353
377
  /** 商品价格 */
354
378
  product_price?: string;
355
379
  /** 商品副标题 */
@@ -370,6 +394,8 @@ export interface SkuValue {
370
394
  product_variant_id: number;
371
395
  /** 多规格商品选项字符串 */
372
396
  product_option_string?: string;
397
+ /** 当前商品或组合规格商品的生产编码 */
398
+ production_code?: string;
373
399
  /** 套餐商品组数据 */
374
400
  bundle: Array<any>;
375
401
  /** 单规格组数据 */
@@ -666,6 +692,44 @@ const App = () => {
666
692
  />
667
693
  ```
668
694
 
695
+ ### 6.7 Option 高级限制与 Production Code
696
+
697
+ 多选 Option Group 在 `metadata.advanced_settings_enabled=1` 时支持种类数限制:
698
+
699
+ ```typescript
700
+ {
701
+ is_multiple: 1,
702
+ min_quantity: 1, // 总份数下限
703
+ max_quantity: 4, // 总份数上限,0 表示不限
704
+ metadata: {
705
+ advanced_settings_enabled: 1,
706
+ option_types_config: {
707
+ min: 1, // 最少种类数,0 表示不限
708
+ max: 2, // 最多种类数,0 表示不限
709
+ },
710
+ },
711
+ option_item: [
712
+ {
713
+ id: 1,
714
+ min_quantity: 2, // 选择该项后的最少份数
715
+ max_quantity: 0, // 单项份数不限
716
+ production_code: 'OPTION-1',
717
+ },
718
+ ],
719
+ }
720
+ ```
721
+
722
+ 达到最多种类数后,组件只禁用尚未选择的 Option Item;已选项仍可在总份数和单项规则允许的范围内调整。Item `min_quantity` 仅对已选项生效,首次选择会从该最小数量开始。
723
+
724
+ `getTransformValues()` 和 `onChange` 输出会明确携带以下编码:
725
+
726
+ - `production_code`:Product 或当前 Variant 编码。
727
+ - `option[*].production_code`:Option Item 编码。
728
+ - `bundle[*].production_code`:Bundle Item 编码。
729
+ - `bundle[*].option[*].production_code`:套餐嵌套 Option Item 编码。
730
+
731
+ 显式空字符串表示“无编码”,不会回退到 Product 或其他节点编码。
732
+
669
733
  ## 7. 注意事项
670
734
 
671
735
  1. **数据格式**:确保传入的 `dataSource` 和 `value` 格式正确,否则可能导致组件渲染异常
@@ -90,6 +90,10 @@ interface IProps {
90
90
  };
91
91
  }
92
92
  interface DataSource {
93
+ /** 商品id */
94
+ id?: number;
95
+ /** 生产编码 */
96
+ production_code?: string;
93
97
  /** 单规格组数据 */
94
98
  option_group?: Array<OptionGroupItem>;
95
99
  /** 组合规格组装后的数据 */
@@ -97,7 +101,19 @@ interface DataSource {
97
101
  /** 组合规格组数据 */
98
102
  variant_group?: Array<VariantGroupItem>;
99
103
  /** 套餐商品组数据 */
100
- bundle_group?: Array<BundleItem>;
104
+ bundle_group?: Array<BundleGroupItem>;
105
+ }
106
+ interface OptionGroupMetadata {
107
+ /** 是否启用高级设置 */
108
+ advanced_settings_enabled?: 0 | 1;
109
+ /** Option 种类数限制 */
110
+ option_types_config?: {
111
+ min?: number;
112
+ max?: number;
113
+ [key: string]: unknown;
114
+ };
115
+ /** 保留后端返回的其他元数据 */
116
+ [key: string]: unknown;
101
117
  }
102
118
  /**
103
119
  * 单规格组数据
@@ -125,6 +141,8 @@ interface OptionGroupItem {
125
141
  max_quantity?: number;
126
142
  /** 最小选择数量 */
127
143
  min_quantity?: number;
144
+ /** 高级设置元数据 */
145
+ metadata?: OptionGroupMetadata;
128
146
  /** 单规格组名称 */
129
147
  name?: string;
130
148
  /** 单规格组下规格数据 */
@@ -168,6 +186,8 @@ interface OptionItem {
168
186
  is_enabled?: 0 | 1;
169
187
  /** 最大选择数量 */
170
188
  max_quantity?: number;
189
+ /** 最小选择数量 */
190
+ min_quantity?: number;
171
191
  /** 规格名称 */
172
192
  name?: string;
173
193
  /** 规格组id */
@@ -176,6 +196,8 @@ interface OptionItem {
176
196
  original_price?: string;
177
197
  /** 商品id */
178
198
  product_id?: number;
199
+ /** 生产编码 */
200
+ production_code?: string;
179
201
  /** 店铺id */
180
202
  shop_id?: number;
181
203
  /** 排序 */
@@ -297,6 +319,8 @@ interface VariantProductItem {
297
319
  price?: string;
298
320
  /** 商品id */
299
321
  product_id?: number;
322
+ /** 生产编码 */
323
+ production_code?: string;
300
324
  /** 折扣类型 */
301
325
  rebate_type?: string;
302
326
  /** 折扣值 */
@@ -312,6 +336,27 @@ interface VariantProductItem {
312
336
  /** 重量值 */
313
337
  weight_value?: string;
314
338
  }
339
+ /**
340
+ * 套餐商品组数据
341
+ */
342
+ interface BundleGroupItem {
343
+ /** 店铺id */
344
+ shop_id?: number;
345
+ /** 排序 */
346
+ sort?: number;
347
+ /** 套餐id */
348
+ id?: number;
349
+ /** 最大选择数量 */
350
+ max_quantity?: number;
351
+ /** 最小选择数量 */
352
+ min_quantity?: number;
353
+ /** 套餐名称 */
354
+ name?: string;
355
+ /** 商品id */
356
+ product_id?: number;
357
+ /** 套餐商品组数据 */
358
+ bundle_item?: Array<BundleItem>;
359
+ }
315
360
  /**
316
361
  * 套餐商品组下选项数据
317
362
  */
@@ -354,6 +399,8 @@ interface BundleItem {
354
399
  price_type_ext?: '' | 'product_price';
355
400
  /** 商品id */
356
401
  product_id?: number;
402
+ /** 生产编码 */
403
+ production_code?: string;
357
404
  /** 商品价格 */
358
405
  product_price?: string;
359
406
  /** 商品副标题 */
@@ -373,6 +420,8 @@ interface SkuValue {
373
420
  product_variant_id: number;
374
421
  /** 多规格商品选项字符串 */
375
422
  product_option_string?: string;
423
+ /** 当前商品或组合规格商品的生产编码 */
424
+ production_code?: string;
376
425
  /** 套餐商品组数据 */
377
426
  bundle: Array<any>;
378
427
  /** 价格 */
@@ -0,0 +1,19 @@
1
+ //#region src/plus/skuOptionsSelection/utils/normalizers.ts
2
+ const normalizeNonNegativeInteger = (value, fallback = 0) => {
3
+ const normalizedFallback = Math.max(0, Math.trunc(Number(fallback) || 0));
4
+ if (value === null || value === void 0 || typeof value === "string" && value.trim() === "") return normalizedFallback;
5
+ const normalizedValue = Number(value);
6
+ if (!Number.isFinite(normalizedValue)) return normalizedFallback;
7
+ return Math.max(0, Math.trunc(normalizedValue));
8
+ };
9
+ const hasOwnProductionCode = (value) => !!value && typeof value === "object" && Object.prototype.hasOwnProperty.call(value, "production_code");
10
+ const normalizeProductionCode = (value) => value === null || value === void 0 ? "" : String(value).trim();
11
+ const resolveProductionCode = (snapshotValue, currentValue) => {
12
+ if (hasOwnProductionCode(snapshotValue)) return normalizeProductionCode(snapshotValue.production_code);
13
+ if (hasOwnProductionCode(currentValue)) return normalizeProductionCode(currentValue.production_code);
14
+ return "";
15
+ };
16
+ //#endregion
17
+ exports.hasOwnProductionCode = hasOwnProductionCode;
18
+ exports.normalizeNonNegativeInteger = normalizeNonNegativeInteger;
19
+ exports.resolveProductionCode = resolveProductionCode;