@pisell/private-materials 6.12.357 → 6.12.359

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.
@@ -112,14 +112,17 @@ const CartItem = ({ onNext, renderContactInfo }) => {
112
112
  if ((res === null || res === void 0 ? void 0 : res.status) === "success") {
113
113
  let result = void 0;
114
114
  if (formId) {
115
- const { formRecordId, mainField } = handleCartHolderFormSuccess({
115
+ const { formRecordId, formId: holderFormId } = handleCartHolderFormSuccess({
116
116
  res,
117
117
  formId,
118
118
  skuRelationFormId,
119
119
  utils,
120
120
  module: appointmentBooking
121
121
  });
122
- result = buildCartHolderOption(_objectSpread2(_objectSpread2({}, res === null || res === void 0 ? void 0 : res.values), {}, { formRecordId }), utils);
122
+ result = buildCartHolderOption(_objectSpread2(_objectSpread2({}, res === null || res === void 0 ? void 0 : res.values), {}, {
123
+ formRecordId,
124
+ form_id: holderFormId
125
+ }), utils);
123
126
  appointmentBooking.updateCart({
124
127
  _id: e === null || e === void 0 ? void 0 : e._id,
125
128
  account: result
@@ -2,6 +2,7 @@ import useEngineContext from "../../hooks/useEngineContext.js";
2
2
  import { _objectSpread2 } from "../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
3
3
  import NumericStepper from "../../pro/NumericStepper/index.js";
4
4
  import index from "../productSelect/components/pisellPriceText/index.js";
5
+ import { resolveProductPricePresentation } from "../productSelect/pricing/pricePresentation.js";
5
6
  import SettlementPriceList from "../multiCurrencySettlement/SettlementPriceList.js";
6
7
  import locales_default from "./locales.js";
7
8
  import { cubicBezier } from "./utils.js";
@@ -58,7 +59,7 @@ function isNormalProduct(product) {
58
59
  return !(hasOption || hasBundle || hasVariant || requiresDetail);
59
60
  }
60
61
  const PisellSalesProductCard = ({ product, requiresOptions = false, hideAction = false, value, selectedQuantity: selectedQuantityProp, disabled = false, soldOut = false, purchaseDisabled = false, stepperProps, optionsText, skuCardConfig, cartElementId, style, className, settlementPriceRows, onChange, onClick }) => {
61
- var _context$appHelper$ut, _product$metadata2, _product$price, _value$num, _stepperProps$min3, _stepperProps$step;
62
+ var _context$appHelper$ut, _product$price, _product$metadata2, _pricePresentation$am, _value$num, _stepperProps$min3, _stepperProps$step;
62
63
  const context = useEngineContext();
63
64
  locales.init(locales_default, ((_context$appHelper$ut = context.appHelper.utils) === null || _context$appHelper$ut === void 0 || (_context$appHelper$ut = _context$appHelper$ut.storage) === null || _context$appHelper$ut === void 0 ? void 0 : _context$appHelper$ut.get("umi_locale")) || "en");
64
65
  const normalProduct = useMemo(() => !requiresOptions && isNormalProduct(product), [product, requiresOptions]);
@@ -69,6 +70,7 @@ const PisellSalesProductCard = ({ product, requiresOptions = false, hideAction =
69
70
  const soldOutIcon = String(locales.locale || "").toLowerCase().startsWith("zh") ? SOLD_OUT_ICON_URLS.cn : SOLD_OUT_ICON_URLS.en;
70
71
  const title = resolveText((product === null || product === void 0 ? void 0 : product.title) || (product === null || product === void 0 ? void 0 : product.name));
71
72
  const textCover = getTextCover(title);
73
+ const pricePresentation = (settlementPriceRows === null || settlementPriceRows === void 0 ? void 0 : settlementPriceRows.length) ? void 0 : resolveProductPricePresentation(product, { price: (_product$price = product.price) !== null && _product$price !== void 0 ? _product$price : 0 });
72
74
  const promotionTags = useMemo(() => {
73
75
  var _product$metadata;
74
76
  const rawPromotionTags = (product === null || product === void 0 ? void 0 : product._promotionTags) || (product === null || product === void 0 || (_product$metadata = product.metadata) === null || _product$metadata === void 0 ? void 0 : _product$metadata._promotionTags) || [];
@@ -167,8 +169,11 @@ const PisellSalesProductCard = ({ product, requiresOptions = false, hideAction =
167
169
  src: soldOutIcon,
168
170
  alt: ""
169
171
  })) : null), /* @__PURE__ */ React.createElement("div", { className: `${PREFIX}__content` }, /* @__PURE__ */ React.createElement("div", { className: `${PREFIX}__title` }, title), (settlementPriceRows === null || settlementPriceRows === void 0 ? void 0 : settlementPriceRows.length) ? /* @__PURE__ */ React.createElement(SettlementPriceList, { rows: settlementPriceRows }) : /* @__PURE__ */ React.createElement(index, {
170
- value: (_product$price = product.price) !== null && _product$price !== void 0 ? _product$price : 0,
171
- isMini: !!product.is_bundle
172
+ value: (_pricePresentation$am = pricePresentation === null || pricePresentation === void 0 ? void 0 : pricePresentation.amount) !== null && _pricePresentation$am !== void 0 ? _pricePresentation$am : 0,
173
+ isMini: (pricePresentation === null || pricePresentation === void 0 ? void 0 : pricePresentation.qualifier) === "from",
174
+ precision: pricePresentation === null || pricePresentation === void 0 ? void 0 : pricePresentation.precision,
175
+ hideDecimalForWholeNumbers: (pricePresentation === null || pricePresentation === void 0 ? void 0 : pricePresentation.precision) ? false : void 0,
176
+ suffix: (pricePresentation === null || pricePresentation === void 0 ? void 0 : pricePresentation.unit) ? /* @__PURE__ */ React.createElement("span", null, "/", pricePresentation.unit) : void 0
172
177
  }), promotionTags.length ? /* @__PURE__ */ React.createElement("div", { className: `${PREFIX}__promotions` }, promotionTags.map((promotionTag, index) => /* @__PURE__ */ React.createElement("span", {
173
178
  key: `${promotionTag}-${index}`,
174
179
  className: `${PREFIX}__promotion-tag`
@@ -1,10 +1,10 @@
1
1
  import { _objectSpread2 } from "../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
2
2
  import dayjs from "dayjs";
3
- import timezone from "dayjs/plugin/timezone";
4
- import utc from "dayjs/plugin/utc";
3
+ import timezonePlugin from "dayjs/plugin/timezone";
4
+ import utcPlugin from "dayjs/plugin/utc";
5
5
  //#region src/plus/saasDevice/devicePasscodes/model.ts
6
- dayjs.extend(utc);
7
- dayjs.extend(timezone);
6
+ dayjs.extend(utcPlugin);
7
+ dayjs.extend(timezonePlugin);
8
8
  const INITIAL_DEVICE_PASSCODE_STATE = {
9
9
  deviceIds: [],
10
10
  devicesById: {}
@@ -6,12 +6,12 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react";
6
6
  import { locales } from "@pisell/utils";
7
7
  import { Button, PisellEmpty, PisellModal, PisellStatisticList, Skeleton, Timeline, usePisellConfig } from "@pisell/materials";
8
8
  import { useRequest } from "ahooks";
9
- import timezone from "dayjs/plugin/timezone";
10
- import utc from "dayjs/plugin/utc";
9
+ import timezonePlugin from "dayjs/plugin/timezone";
10
+ import utcPlugin from "dayjs/plugin/utc";
11
11
  import "./index.less";
12
12
  //#region src/plus/walletPassGallery/components/timelineSection/index.tsx
13
- dayjs.extend(timezone);
14
- dayjs.extend(utc);
13
+ dayjs.extend(timezonePlugin);
14
+ dayjs.extend(utcPlugin);
15
15
  const stateTimeUnix = 1723255863;
16
16
  const POLL_INTERVAL = 2e3;
17
17
  const POLL_MAX_TIMES = 5;
@@ -25,6 +25,7 @@ import locales_default$1 from "./flow/locales.js";
25
25
  import { isRememberTimeProduct, isRememberedTimeIntent, requiresManualTimeSelection } from "./flow/rememberTime.js";
26
26
  import { resolveDetailAppearance } from "./appearances/index.js";
27
27
  import useToast$1 from "../../hooks/useToast.js";
28
+ import { createSkuNoteDiagnostics } from "./noteDiagnostics.js";
28
29
  import SkuDetailLoadingPanel from "./LoadingPanel.js";
29
30
  import SkuDetailCollapsibleSection from "./components/CollapsibleSection/index.js";
30
31
  import { getProductSkuFromWeighingValue, getWeighedUnitPrice, getWeighingValueFromProductSku, hasPositiveNetWeight, isWeighingProduct, resolveActiveSkuValue } from "./components/weighing/utils.js";
@@ -240,6 +241,13 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
240
241
  const selectionFlowCanScrollDownRef = useRef(false);
241
242
  const Toast = useToast$1();
242
243
  const logger = useLogger();
244
+ const loggerRef = useRef(logger);
245
+ loggerRef.current = logger;
246
+ const noteDiagnosticsRef = useRef(null);
247
+ useEffect(() => () => {
248
+ var _noteDiagnosticsRef$c;
249
+ return (_noteDiagnosticsRef$c = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c === void 0 ? void 0 : _noteDiagnosticsRef$c.stop();
250
+ }, []);
243
251
  /**
244
252
  * @description SKUOptionsSelection ref,用于触发内部校验与读取最终值
245
253
  */
@@ -923,7 +931,9 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
923
931
  },
924
932
  open: function() {
925
933
  var _ref17 = _asyncToGenerator(function* (data) {
926
- var _skuDetailConfig$enab, _skuDetailConfig$isSh, _skuDetailConfig$isSh2, _skuDetailConfig$isSh3, _skuDetailConfig$isSh4, _skuDetailConfig$isSh5, _skuDetailConfig$hide, _skuDetailConfig$isSh6, _skuDetailConfig$isSh7, _skuDetailConfig$isSh8, _skuDetailConfig$exte, _skuDetailConfig$useC, _skuDetailConfig$cust, _skuDetailConfig$isCa, _skuDetailConfig, _skuDetailConfig2, _data$bundle_group, _data$_extend, _data$_extend2, _data$discount_list, _ref15, _data$_extend3, _data$_extend4, _data$_extend5, _data$discount_list$f, _data$discount_list2, _ref16, _data$_extend$priceOv, _data$_extend7;
934
+ var _noteDiagnosticsRef$c2, _product_id, _skuDetailConfig$enab, _skuDetailConfig$isSh, _skuDetailConfig$isSh2, _skuDetailConfig$isSh3, _skuDetailConfig$isSh4, _skuDetailConfig$isSh5, _skuDetailConfig$hide, _skuDetailConfig$isSh6, _skuDetailConfig$isSh7, _skuDetailConfig$isSh8, _skuDetailConfig$exte, _skuDetailConfig$useC, _skuDetailConfig$cust, _skuDetailConfig$isCa, _skuDetailConfig, _skuDetailConfig2, _data$bundle_group, _data$_extend, _data$_extend2, _data$discount_list, _ref15, _data$_extend3, _data$_extend4, _data$_extend5, _data$discount_list$f, _data$discount_list2, _ref16, _data$_extend$priceOv, _data$_extend7;
935
+ (_noteDiagnosticsRef$c2 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c2 === void 0 || _noteDiagnosticsRef$c2.stop();
936
+ noteDiagnosticsRef.current = createSkuNoteDiagnostics(() => loggerRef.current, (_product_id = data.product_id) !== null && _product_id !== void 0 ? _product_id : data.id, "date" in data && !("_extend" in data) ? "create" : "edit");
927
937
  selectionFlowOpenedAtRef.current = dayjs().toISOString();
928
938
  const currentTaskId = openTaskIdRef.current + 1;
929
939
  openTaskIdRef.current = currentTaskId;
@@ -1250,6 +1260,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
1250
1260
  };
1251
1261
  }(),
1252
1262
  close: () => {
1263
+ var _noteDiagnosticsRef$c3;
1264
+ (_noteDiagnosticsRef$c3 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c3 === void 0 || _noteDiagnosticsRef$c3.stop();
1253
1265
  openTaskIdRef.current += 1;
1254
1266
  setOpen(false);
1255
1267
  setDetailLoading(false);
@@ -1483,6 +1495,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
1483
1495
  * @description 关闭动画结束后再清空详情态,避免退出动画期间因 productData 为空闪回骨架屏。
1484
1496
  */
1485
1497
  const resetModalStateAfterClose = useCallback(() => {
1498
+ var _noteDiagnosticsRef$c4;
1499
+ (_noteDiagnosticsRef$c4 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c4 === void 0 || _noteDiagnosticsRef$c4.stop();
1486
1500
  setProductData(null);
1487
1501
  setDetailLoading(false);
1488
1502
  setNote("");
@@ -1506,6 +1520,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
1506
1520
  lateQuantityRevalidationTaskRef.current = null;
1507
1521
  }, []);
1508
1522
  const modalCloseAction = () => {
1523
+ var _noteDiagnosticsRef$c5;
1524
+ (_noteDiagnosticsRef$c5 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c5 === void 0 || _noteDiagnosticsRef$c5.stop();
1509
1525
  openTaskIdRef.current += 1;
1510
1526
  flowDateHydrationVersionRef.current += 1;
1511
1527
  lateQuantityReviewStepIndexRef.current = null;
@@ -1528,7 +1544,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
1528
1544
  };
1529
1545
  const handleConfirm = function() {
1530
1546
  var _ref18 = _asyncToGenerator(function* (flowDraft) {
1531
- var _bookingState$booking3, _selectionFlowRef$cur8, _selectionFlowService3;
1547
+ var _noteDiagnosticsRef$c6, _bookingState$booking3, _selectionFlowRef$cur8, _selectionFlowService3;
1548
+ (_noteDiagnosticsRef$c6 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c6 === void 0 || _noteDiagnosticsRef$c6.skuConfirm(note.length);
1532
1549
  if (confirmDisabledRef.current) return false;
1533
1550
  if (flowDraft && requiresManualTimeSelection(flowDraft)) return false;
1534
1551
  if (isCustomSelectionFlow && !flowDraft) {
@@ -1850,17 +1867,28 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
1850
1867
  productData === null || productData === void 0 ? void 0 : productData._id,
1851
1868
  productData === null || productData === void 0 ? void 0 : productData.id
1852
1869
  ]);
1870
+ const onOpenNote = () => {
1871
+ var _noteDiagnosticsRef$c7;
1872
+ (_noteDiagnosticsRef$c7 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c7 === void 0 || _noteDiagnosticsRef$c7.open(note.length);
1873
+ setNoteModalOpen(true);
1874
+ };
1853
1875
  const onNoteConfirm = (note) => {
1876
+ var _noteDiagnosticsRef$c8;
1877
+ (_noteDiagnosticsRef$c8 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c8 === void 0 || _noteDiagnosticsRef$c8.confirm(note.length);
1854
1878
  setNote(note);
1855
1879
  updateCustomFlowDraft({ note }, ["note"]);
1856
1880
  setNoteModalOpen(false);
1857
1881
  };
1858
1882
  const onNoteDelete = () => {
1883
+ var _noteDiagnosticsRef$c9;
1884
+ (_noteDiagnosticsRef$c9 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c9 === void 0 || _noteDiagnosticsRef$c9.stop();
1859
1885
  setNote("");
1860
1886
  updateCustomFlowDraft({ note: "" }, ["note"]);
1861
1887
  setNoteModalOpen(false);
1862
1888
  };
1863
1889
  const onNoteCancel = () => {
1890
+ var _noteDiagnosticsRef$c10;
1891
+ (_noteDiagnosticsRef$c10 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c10 === void 0 || _noteDiagnosticsRef$c10.stop();
1864
1892
  setNoteModalOpen(false);
1865
1893
  };
1866
1894
  const handleManualPriceChange = () => {
@@ -1996,7 +2024,7 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
1996
2024
  max: 99999
1997
2025
  })), note && /* @__PURE__ */ React.createElement("div", { className: "note-section note-section-right" }, /* @__PURE__ */ React.createElement("div", { className: "note-label" }, locales.getText("pisell2.text.sku.detail.modal.note")), /* @__PURE__ */ React.createElement("div", {
1998
2026
  className: "note-text",
1999
- onClick: () => setNoteModalOpen(true)
2027
+ onClick: onOpenNote
2000
2028
  }, note))), /* @__PURE__ */ React.createElement("div", { className: "price-summary-section" }, !isVirtualOnlySettlement ? /* @__PURE__ */ React.createElement("div", { className: "price-item" }, /* @__PURE__ */ React.createElement("div", null, locales.getText("pisell2.text.sku.detail.modal.subtotal")), /* @__PURE__ */ React.createElement("div", null, subtotalText)) : null, !isVirtualOnlySettlement ? /* @__PURE__ */ React.createElement("div", { className: "price-item" }, /* @__PURE__ */ React.createElement("div", null, locales.getText("pisell2.text.sku.detail.modal.discount"), discountsCount > 0 && /* @__PURE__ */ React.createElement("span", { className: "price-item-danger" }, "\xA0(", discountsCount, ")")), /* @__PURE__ */ React.createElement("div", { className: "price-item-danger" }, discountsCount > 0 ? "-" : "", symbol, totalDiscounts)) : null, !isVirtualOnlySettlement && priceOverride !== null && typeof priceOverride !== "undefined" && /* @__PURE__ */ React.createElement("div", { className: "price-item" }, /* @__PURE__ */ React.createElement("div", { onClick: handleManualPriceChange }, locales.getText("pisell2.text.sku.detail.modal.manual.price.change"), /* @__PURE__ */ React.createElement("span", { className: "price-item-override" }, priceOverrideText)), /* @__PURE__ */ React.createElement("div", { className: "price-item-danger" }, priceChangeText)), /* @__PURE__ */ React.createElement("div", { className: "price-item-total" }, /* @__PURE__ */ React.createElement("div", { className: "price-item-total-label" }, locales.getText("pisell2.text.sku.detail.modal.total"), !isVirtualOnlySettlement ? /* @__PURE__ */ React.createElement("span", { className: "price-item-total-gst" }, "(", (productData === null || productData === void 0 ? void 0 : productData.is_charge_tax) ? locales.getText("pisell2.text.sku.detail.modal.gst.incl") : locales.getText("pisell2.text.sku.detail.modal.gst.excl"), ")") : null), /* @__PURE__ */ React.createElement("div", { className: "price-item-total-values" }, !isVirtualOnlySettlement ? /* @__PURE__ */ React.createElement("div", { className: "price-item-total-value" }, totalText) : null, virtualSettlementTotals.map(({ option, text }) => /* @__PURE__ */ React.createElement("div", {
2001
2029
  key: `virtual:${String(option.currency_product_id || option.data_variant_id)}`,
2002
2030
  className: `price-item-total-settlement-value${option.available === false ? " is-disabled" : ""}`,
@@ -2014,7 +2042,7 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
2014
2042
  onCancel: handleCancel,
2015
2043
  onRemove: handleRemove,
2016
2044
  onManualPriceChange: handleManualPriceChange,
2017
- onOpenNote: () => setNoteModalOpen(true),
2045
+ onOpenNote,
2018
2046
  onConfirm: () => {
2019
2047
  handleConfirm();
2020
2048
  }
@@ -2271,7 +2299,7 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
2271
2299
  type: "button",
2272
2300
  className: "sku-detail-appearance__note",
2273
2301
  disabled: appearanceConfirmPending,
2274
- onClick: () => setNoteModalOpen(true)
2302
+ onClick: onOpenNote
2275
2303
  }, note || locales.getText("pisell2.text.sku.detail.modal.btn.add.note")),
2276
2304
  removeControl: !isCreateMode && skuDetailConfig.isShowRemove !== false && onRemove && /* @__PURE__ */ React.createElement("button", {
2277
2305
  type: "button",
@@ -0,0 +1,110 @@
1
+ //#region src/pro/skuDetailModal/noteDiagnostics.ts
2
+ const VIEWPORT_INTERVAL_MS = 250;
3
+ const MAX_VIEWPORT_EVENTS = 10;
4
+ /** SKU 内默认启用;不修改 NoteModal 接口或商品数据。 */
5
+ function createSkuNoteDiagnostics(getLogger, productId, mode) {
6
+ const startedAtMs = Date.now();
7
+ const traceId = `sku-note-${startedAtMs}-${Math.random().toString(36).slice(2)}`;
8
+ let seq = 0;
9
+ let noteLength = 0;
10
+ let opened = false;
11
+ let active = false;
12
+ let noteAttempt = 0;
13
+ let skuConfirmLogged = false;
14
+ let cleanup = () => {};
15
+ const seen = /* @__PURE__ */ new Set();
16
+ const log = (event, source) => {
17
+ try {
18
+ var _getLogger, _document$body;
19
+ const capturedAtMs = Date.now();
20
+ const viewport = window.visualViewport;
21
+ (_getLogger = getLogger()) === null || _getLogger === void 0 || _getLogger.addLog({
22
+ type: "info",
23
+ title: event,
24
+ metadata: {
25
+ module: "SkuNoteDiagnostics",
26
+ category: "performance",
27
+ traceId,
28
+ seq: ++seq,
29
+ capturedAtMs,
30
+ elapsedMs: Math.max(0, capturedAtMs - startedAtMs),
31
+ productId,
32
+ mode,
33
+ noteAttempt,
34
+ noteLength,
35
+ source,
36
+ viewport: {
37
+ innerWidth: window.innerWidth,
38
+ innerHeight: window.innerHeight,
39
+ visualViewport: viewport ? {
40
+ width: viewport.width,
41
+ height: viewport.height,
42
+ offsetTop: viewport.offsetTop,
43
+ scale: viewport.scale
44
+ } : null,
45
+ bodyTransform: ((_document$body = document.body) === null || _document$body === void 0 ? void 0 : _document$body.style.transform) || ""
46
+ }
47
+ }
48
+ });
49
+ } catch (_unused) {}
50
+ };
51
+ const stop = () => {
52
+ active = false;
53
+ cleanup();
54
+ cleanup = () => {};
55
+ };
56
+ return {
57
+ open(length) {
58
+ stop();
59
+ opened = active = true;
60
+ noteLength = length;
61
+ noteAttempt += 1;
62
+ seen.clear();
63
+ let count = 0;
64
+ let lastAt = -Infinity;
65
+ const onResize = (event) => {
66
+ const now = Date.now();
67
+ if (!active || count >= MAX_VIEWPORT_EVENTS || now - lastAt < VIEWPORT_INTERVAL_MS) return;
68
+ lastAt = now;
69
+ count += 1;
70
+ log("note_viewport_change", event.currentTarget === window ? "window" : "visualViewport");
71
+ };
72
+ const onNoteEvent = (event) => {
73
+ const target = event.target;
74
+ if (!active || !(target instanceof HTMLTextAreaElement) || !target.closest(".note-modal-content .note-input")) return;
75
+ noteLength = target.value.length;
76
+ const title = event.type === "focusin" ? "note_focus" : "note_first_input";
77
+ if (seen.has(title)) return;
78
+ seen.add(title);
79
+ log(title);
80
+ };
81
+ const visualViewport = window.visualViewport;
82
+ window.addEventListener("resize", onResize);
83
+ visualViewport === null || visualViewport === void 0 || visualViewport.addEventListener("resize", onResize);
84
+ document.addEventListener("focusin", onNoteEvent, true);
85
+ document.addEventListener("input", onNoteEvent, true);
86
+ cleanup = () => {
87
+ window.removeEventListener("resize", onResize);
88
+ visualViewport === null || visualViewport === void 0 || visualViewport.removeEventListener("resize", onResize);
89
+ document.removeEventListener("focusin", onNoteEvent, true);
90
+ document.removeEventListener("input", onNoteEvent, true);
91
+ };
92
+ log("note_open");
93
+ },
94
+ confirm(length) {
95
+ if (!active) return;
96
+ noteLength = length;
97
+ log("note_confirm");
98
+ stop();
99
+ },
100
+ stop,
101
+ skuConfirm(length) {
102
+ if (!opened || skuConfirmLogged) return;
103
+ skuConfirmLogged = true;
104
+ noteLength = length;
105
+ log("sku_confirm");
106
+ }
107
+ };
108
+ }
109
+ //#endregion
110
+ export { createSkuNoteDiagnostics };
@@ -48,7 +48,10 @@ const createCartHolderOption = (holder, customerId) => {
48
48
  name: holder === null || holder === void 0 ? void 0 : holder.main_field,
49
49
  username: holder === null || holder === void 0 ? void 0 : holder.main_field,
50
50
  type: "holder",
51
- _origin: _objectSpread2(_objectSpread2({}, holder), {}, { customer_id: customerId })
51
+ _origin: _objectSpread2(_objectSpread2({}, holder), {}, {
52
+ form_record_id: _id,
53
+ customer_id: customerId
54
+ })
52
55
  };
53
56
  };
54
57
  /**
@@ -114,14 +114,17 @@ const CartItem = ({ onNext, renderContactInfo }) => {
114
114
  if ((res === null || res === void 0 ? void 0 : res.status) === "success") {
115
115
  let result = void 0;
116
116
  if (formId) {
117
- const { formRecordId, mainField } = require_buildCartHolderParams.handleCartHolderFormSuccess({
117
+ const { formRecordId, formId: holderFormId } = require_buildCartHolderParams.handleCartHolderFormSuccess({
118
118
  res,
119
119
  formId,
120
120
  skuRelationFormId,
121
121
  utils,
122
122
  module: appointmentBooking
123
123
  });
124
- result = require_buildCartHolderParams.buildCartHolderOption(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, res === null || res === void 0 ? void 0 : res.values), {}, { formRecordId }), utils);
124
+ result = require_buildCartHolderParams.buildCartHolderOption(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, res === null || res === void 0 ? void 0 : res.values), {}, {
125
+ formRecordId,
126
+ form_id: holderFormId
127
+ }), utils);
125
128
  appointmentBooking.updateCart({
126
129
  _id: e === null || e === void 0 ? void 0 : e._id,
127
130
  account: result
@@ -3,6 +3,7 @@ const require_useEngineContext = require("../../hooks/useEngineContext.js");
3
3
  const require_objectSpread2 = require("../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
4
4
  const require_index = require("../../pro/NumericStepper/index.js");
5
5
  const require_index$1 = require("../productSelect/components/pisellPriceText/index.js");
6
+ const require_pricePresentation = require("../productSelect/pricing/pricePresentation.js");
6
7
  const require_SettlementPriceList = require("../multiCurrencySettlement/SettlementPriceList.js");
7
8
  const require_locales = require("./locales.js");
8
9
  const require_utils = require("./utils.js");
@@ -63,7 +64,7 @@ function isNormalProduct(product) {
63
64
  return !(hasOption || hasBundle || hasVariant || requiresDetail);
64
65
  }
65
66
  const PisellSalesProductCard = ({ product, requiresOptions = false, hideAction = false, value, selectedQuantity: selectedQuantityProp, disabled = false, soldOut = false, purchaseDisabled = false, stepperProps, optionsText, skuCardConfig, cartElementId, style, className, settlementPriceRows, onChange, onClick }) => {
66
- var _context$appHelper$ut, _product$metadata2, _product$price, _value$num, _stepperProps$min3, _stepperProps$step;
67
+ var _context$appHelper$ut, _product$price, _product$metadata2, _pricePresentation$am, _value$num, _stepperProps$min3, _stepperProps$step;
67
68
  const context = require_useEngineContext.default();
68
69
  _pisell_utils.locales.init(require_locales.default, ((_context$appHelper$ut = context.appHelper.utils) === null || _context$appHelper$ut === void 0 || (_context$appHelper$ut = _context$appHelper$ut.storage) === null || _context$appHelper$ut === void 0 ? void 0 : _context$appHelper$ut.get("umi_locale")) || "en");
69
70
  const normalProduct = (0, react.useMemo)(() => !requiresOptions && isNormalProduct(product), [product, requiresOptions]);
@@ -74,6 +75,7 @@ const PisellSalesProductCard = ({ product, requiresOptions = false, hideAction =
74
75
  const soldOutIcon = String(_pisell_utils.locales.locale || "").toLowerCase().startsWith("zh") ? SOLD_OUT_ICON_URLS.cn : SOLD_OUT_ICON_URLS.en;
75
76
  const title = resolveText((product === null || product === void 0 ? void 0 : product.title) || (product === null || product === void 0 ? void 0 : product.name));
76
77
  const textCover = getTextCover(title);
78
+ const pricePresentation = (settlementPriceRows === null || settlementPriceRows === void 0 ? void 0 : settlementPriceRows.length) ? void 0 : require_pricePresentation.resolveProductPricePresentation(product, { price: (_product$price = product.price) !== null && _product$price !== void 0 ? _product$price : 0 });
77
79
  const promotionTags = (0, react.useMemo)(() => {
78
80
  var _product$metadata;
79
81
  const rawPromotionTags = (product === null || product === void 0 ? void 0 : product._promotionTags) || (product === null || product === void 0 || (_product$metadata = product.metadata) === null || _product$metadata === void 0 ? void 0 : _product$metadata._promotionTags) || [];
@@ -172,8 +174,11 @@ const PisellSalesProductCard = ({ product, requiresOptions = false, hideAction =
172
174
  src: soldOutIcon,
173
175
  alt: ""
174
176
  })) : null), /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}__content` }, /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}__title` }, title), (settlementPriceRows === null || settlementPriceRows === void 0 ? void 0 : settlementPriceRows.length) ? /* @__PURE__ */ react.default.createElement(require_SettlementPriceList.default, { rows: settlementPriceRows }) : /* @__PURE__ */ react.default.createElement(require_index$1.default, {
175
- value: (_product$price = product.price) !== null && _product$price !== void 0 ? _product$price : 0,
176
- isMini: !!product.is_bundle
177
+ value: (_pricePresentation$am = pricePresentation === null || pricePresentation === void 0 ? void 0 : pricePresentation.amount) !== null && _pricePresentation$am !== void 0 ? _pricePresentation$am : 0,
178
+ isMini: (pricePresentation === null || pricePresentation === void 0 ? void 0 : pricePresentation.qualifier) === "from",
179
+ precision: pricePresentation === null || pricePresentation === void 0 ? void 0 : pricePresentation.precision,
180
+ hideDecimalForWholeNumbers: (pricePresentation === null || pricePresentation === void 0 ? void 0 : pricePresentation.precision) ? false : void 0,
181
+ suffix: (pricePresentation === null || pricePresentation === void 0 ? void 0 : pricePresentation.unit) ? /* @__PURE__ */ react.default.createElement("span", null, "/", pricePresentation.unit) : void 0
177
182
  }), promotionTags.length ? /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}__promotions` }, promotionTags.map((promotionTag, index) => /* @__PURE__ */ react.default.createElement("span", {
178
183
  key: `${promotionTag}-${index}`,
179
184
  className: `${PREFIX}__promotion-tag`
@@ -26,6 +26,7 @@ const require_locales$1 = require("./flow/locales.js");
26
26
  const require_rememberTime = require("./flow/rememberTime.js");
27
27
  const require_index$6 = require("./appearances/index.js");
28
28
  const require_useToast = require("../../hooks/useToast.js");
29
+ const require_noteDiagnostics = require("./noteDiagnostics.js");
29
30
  const require_LoadingPanel = require("./LoadingPanel.js");
30
31
  const require_index$7 = require("./components/CollapsibleSection/index.js");
31
32
  const require_utils$4 = require("./components/weighing/utils.js");
@@ -246,6 +247,13 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
246
247
  const selectionFlowCanScrollDownRef = (0, react.useRef)(false);
247
248
  const Toast = require_useToast.default();
248
249
  const logger = require_useLogger.default();
250
+ const loggerRef = (0, react.useRef)(logger);
251
+ loggerRef.current = logger;
252
+ const noteDiagnosticsRef = (0, react.useRef)(null);
253
+ (0, react.useEffect)(() => () => {
254
+ var _noteDiagnosticsRef$c;
255
+ return (_noteDiagnosticsRef$c = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c === void 0 ? void 0 : _noteDiagnosticsRef$c.stop();
256
+ }, []);
249
257
  /**
250
258
  * @description SKUOptionsSelection ref,用于触发内部校验与读取最终值
251
259
  */
@@ -929,7 +937,9 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
929
937
  },
930
938
  open: function() {
931
939
  var _ref17 = require_asyncToGenerator._asyncToGenerator(function* (data) {
932
- var _skuDetailConfig$enab, _skuDetailConfig$isSh, _skuDetailConfig$isSh2, _skuDetailConfig$isSh3, _skuDetailConfig$isSh4, _skuDetailConfig$isSh5, _skuDetailConfig$hide, _skuDetailConfig$isSh6, _skuDetailConfig$isSh7, _skuDetailConfig$isSh8, _skuDetailConfig$exte, _skuDetailConfig$useC, _skuDetailConfig$cust, _skuDetailConfig$isCa, _skuDetailConfig, _skuDetailConfig2, _data$bundle_group, _data$_extend, _data$_extend2, _data$discount_list, _ref15, _data$_extend3, _data$_extend4, _data$_extend5, _data$discount_list$f, _data$discount_list2, _ref16, _data$_extend$priceOv, _data$_extend7;
940
+ var _noteDiagnosticsRef$c2, _product_id, _skuDetailConfig$enab, _skuDetailConfig$isSh, _skuDetailConfig$isSh2, _skuDetailConfig$isSh3, _skuDetailConfig$isSh4, _skuDetailConfig$isSh5, _skuDetailConfig$hide, _skuDetailConfig$isSh6, _skuDetailConfig$isSh7, _skuDetailConfig$isSh8, _skuDetailConfig$exte, _skuDetailConfig$useC, _skuDetailConfig$cust, _skuDetailConfig$isCa, _skuDetailConfig, _skuDetailConfig2, _data$bundle_group, _data$_extend, _data$_extend2, _data$discount_list, _ref15, _data$_extend3, _data$_extend4, _data$_extend5, _data$discount_list$f, _data$discount_list2, _ref16, _data$_extend$priceOv, _data$_extend7;
941
+ (_noteDiagnosticsRef$c2 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c2 === void 0 || _noteDiagnosticsRef$c2.stop();
942
+ noteDiagnosticsRef.current = require_noteDiagnostics.createSkuNoteDiagnostics(() => loggerRef.current, (_product_id = data.product_id) !== null && _product_id !== void 0 ? _product_id : data.id, "date" in data && !("_extend" in data) ? "create" : "edit");
933
943
  selectionFlowOpenedAtRef.current = (0, dayjs.default)().toISOString();
934
944
  const currentTaskId = openTaskIdRef.current + 1;
935
945
  openTaskIdRef.current = currentTaskId;
@@ -1256,6 +1266,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
1256
1266
  };
1257
1267
  }(),
1258
1268
  close: () => {
1269
+ var _noteDiagnosticsRef$c3;
1270
+ (_noteDiagnosticsRef$c3 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c3 === void 0 || _noteDiagnosticsRef$c3.stop();
1259
1271
  openTaskIdRef.current += 1;
1260
1272
  setOpen(false);
1261
1273
  setDetailLoading(false);
@@ -1489,6 +1501,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
1489
1501
  * @description 关闭动画结束后再清空详情态,避免退出动画期间因 productData 为空闪回骨架屏。
1490
1502
  */
1491
1503
  const resetModalStateAfterClose = (0, react.useCallback)(() => {
1504
+ var _noteDiagnosticsRef$c4;
1505
+ (_noteDiagnosticsRef$c4 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c4 === void 0 || _noteDiagnosticsRef$c4.stop();
1492
1506
  setProductData(null);
1493
1507
  setDetailLoading(false);
1494
1508
  setNote("");
@@ -1512,6 +1526,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
1512
1526
  lateQuantityRevalidationTaskRef.current = null;
1513
1527
  }, []);
1514
1528
  const modalCloseAction = () => {
1529
+ var _noteDiagnosticsRef$c5;
1530
+ (_noteDiagnosticsRef$c5 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c5 === void 0 || _noteDiagnosticsRef$c5.stop();
1515
1531
  openTaskIdRef.current += 1;
1516
1532
  flowDateHydrationVersionRef.current += 1;
1517
1533
  lateQuantityReviewStepIndexRef.current = null;
@@ -1534,7 +1550,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
1534
1550
  };
1535
1551
  const handleConfirm = function() {
1536
1552
  var _ref18 = require_asyncToGenerator._asyncToGenerator(function* (flowDraft) {
1537
- var _bookingState$booking3, _selectionFlowRef$cur8, _selectionFlowService3;
1553
+ var _noteDiagnosticsRef$c6, _bookingState$booking3, _selectionFlowRef$cur8, _selectionFlowService3;
1554
+ (_noteDiagnosticsRef$c6 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c6 === void 0 || _noteDiagnosticsRef$c6.skuConfirm(note.length);
1538
1555
  if (confirmDisabledRef.current) return false;
1539
1556
  if (flowDraft && require_rememberTime.requiresManualTimeSelection(flowDraft)) return false;
1540
1557
  if (isCustomSelectionFlow && !flowDraft) {
@@ -1856,17 +1873,28 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
1856
1873
  productData === null || productData === void 0 ? void 0 : productData._id,
1857
1874
  productData === null || productData === void 0 ? void 0 : productData.id
1858
1875
  ]);
1876
+ const onOpenNote = () => {
1877
+ var _noteDiagnosticsRef$c7;
1878
+ (_noteDiagnosticsRef$c7 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c7 === void 0 || _noteDiagnosticsRef$c7.open(note.length);
1879
+ setNoteModalOpen(true);
1880
+ };
1859
1881
  const onNoteConfirm = (note) => {
1882
+ var _noteDiagnosticsRef$c8;
1883
+ (_noteDiagnosticsRef$c8 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c8 === void 0 || _noteDiagnosticsRef$c8.confirm(note.length);
1860
1884
  setNote(note);
1861
1885
  updateCustomFlowDraft({ note }, ["note"]);
1862
1886
  setNoteModalOpen(false);
1863
1887
  };
1864
1888
  const onNoteDelete = () => {
1889
+ var _noteDiagnosticsRef$c9;
1890
+ (_noteDiagnosticsRef$c9 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c9 === void 0 || _noteDiagnosticsRef$c9.stop();
1865
1891
  setNote("");
1866
1892
  updateCustomFlowDraft({ note: "" }, ["note"]);
1867
1893
  setNoteModalOpen(false);
1868
1894
  };
1869
1895
  const onNoteCancel = () => {
1896
+ var _noteDiagnosticsRef$c10;
1897
+ (_noteDiagnosticsRef$c10 = noteDiagnosticsRef.current) === null || _noteDiagnosticsRef$c10 === void 0 || _noteDiagnosticsRef$c10.stop();
1870
1898
  setNoteModalOpen(false);
1871
1899
  };
1872
1900
  const handleManualPriceChange = () => {
@@ -2002,7 +2030,7 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
2002
2030
  max: 99999
2003
2031
  })), note && /* @__PURE__ */ react.default.createElement("div", { className: "note-section note-section-right" }, /* @__PURE__ */ react.default.createElement("div", { className: "note-label" }, _pisell_utils.locales.getText("pisell2.text.sku.detail.modal.note")), /* @__PURE__ */ react.default.createElement("div", {
2004
2032
  className: "note-text",
2005
- onClick: () => setNoteModalOpen(true)
2033
+ onClick: onOpenNote
2006
2034
  }, note))), /* @__PURE__ */ react.default.createElement("div", { className: "price-summary-section" }, !isVirtualOnlySettlement ? /* @__PURE__ */ react.default.createElement("div", { className: "price-item" }, /* @__PURE__ */ react.default.createElement("div", null, _pisell_utils.locales.getText("pisell2.text.sku.detail.modal.subtotal")), /* @__PURE__ */ react.default.createElement("div", null, subtotalText)) : null, !isVirtualOnlySettlement ? /* @__PURE__ */ react.default.createElement("div", { className: "price-item" }, /* @__PURE__ */ react.default.createElement("div", null, _pisell_utils.locales.getText("pisell2.text.sku.detail.modal.discount"), discountsCount > 0 && /* @__PURE__ */ react.default.createElement("span", { className: "price-item-danger" }, "\xA0(", discountsCount, ")")), /* @__PURE__ */ react.default.createElement("div", { className: "price-item-danger" }, discountsCount > 0 ? "-" : "", symbol, totalDiscounts)) : null, !isVirtualOnlySettlement && priceOverride !== null && typeof priceOverride !== "undefined" && /* @__PURE__ */ react.default.createElement("div", { className: "price-item" }, /* @__PURE__ */ react.default.createElement("div", { onClick: handleManualPriceChange }, _pisell_utils.locales.getText("pisell2.text.sku.detail.modal.manual.price.change"), /* @__PURE__ */ react.default.createElement("span", { className: "price-item-override" }, priceOverrideText)), /* @__PURE__ */ react.default.createElement("div", { className: "price-item-danger" }, priceChangeText)), /* @__PURE__ */ react.default.createElement("div", { className: "price-item-total" }, /* @__PURE__ */ react.default.createElement("div", { className: "price-item-total-label" }, _pisell_utils.locales.getText("pisell2.text.sku.detail.modal.total"), !isVirtualOnlySettlement ? /* @__PURE__ */ react.default.createElement("span", { className: "price-item-total-gst" }, "(", (productData === null || productData === void 0 ? void 0 : productData.is_charge_tax) ? _pisell_utils.locales.getText("pisell2.text.sku.detail.modal.gst.incl") : _pisell_utils.locales.getText("pisell2.text.sku.detail.modal.gst.excl"), ")") : null), /* @__PURE__ */ react.default.createElement("div", { className: "price-item-total-values" }, !isVirtualOnlySettlement ? /* @__PURE__ */ react.default.createElement("div", { className: "price-item-total-value" }, totalText) : null, virtualSettlementTotals.map(({ option, text }) => /* @__PURE__ */ react.default.createElement("div", {
2007
2035
  key: `virtual:${String(option.currency_product_id || option.data_variant_id)}`,
2008
2036
  className: `price-item-total-settlement-value${option.available === false ? " is-disabled" : ""}`,
@@ -2020,7 +2048,7 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
2020
2048
  onCancel: handleCancel,
2021
2049
  onRemove: handleRemove,
2022
2050
  onManualPriceChange: handleManualPriceChange,
2023
- onOpenNote: () => setNoteModalOpen(true),
2051
+ onOpenNote,
2024
2052
  onConfirm: () => {
2025
2053
  handleConfirm();
2026
2054
  }
@@ -2277,7 +2305,7 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant, confirmDisabled
2277
2305
  type: "button",
2278
2306
  className: "sku-detail-appearance__note",
2279
2307
  disabled: appearanceConfirmPending,
2280
- onClick: () => setNoteModalOpen(true)
2308
+ onClick: onOpenNote
2281
2309
  }, note || _pisell_utils.locales.getText("pisell2.text.sku.detail.modal.btn.add.note")),
2282
2310
  removeControl: !isCreateMode && skuDetailConfig.isShowRemove !== false && onRemove && /* @__PURE__ */ react.default.createElement("button", {
2283
2311
  type: "button",