@pisell/pisellos 2.2.190 → 2.2.191

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 (67) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +0 -9
  2. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +2 -1
  3. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -7
  4. package/dist/modules/Cart/utils/cartProduct.js +13 -2
  5. package/dist/modules/Order/index.d.ts +1 -3
  6. package/dist/modules/Order/index.js +69 -95
  7. package/dist/modules/Order/types.d.ts +9 -6
  8. package/dist/modules/Order/utils.d.ts +9 -2
  9. package/dist/modules/Order/utils.js +36 -13
  10. package/dist/modules/SalesSummary/types.d.ts +3 -1
  11. package/dist/modules/SalesSummary/utils.js +7 -3
  12. package/dist/server/modules/order/index.d.ts +126 -6
  13. package/dist/server/modules/order/index.js +1204 -285
  14. package/dist/server/modules/order/types.d.ts +0 -2
  15. package/dist/server/modules/products/index.d.ts +90 -6
  16. package/dist/server/modules/products/index.js +1017 -361
  17. package/dist/solution/BaseSales/index.js +13 -7
  18. package/dist/solution/BaseSales/types.d.ts +8 -5
  19. package/dist/solution/BaseSales/types.js +2 -3
  20. package/dist/solution/BaseSales/utils/cartPromotion.js +7 -7
  21. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
  22. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +16 -13
  23. package/dist/solution/BaseSales/utils.d.ts +1 -1
  24. package/dist/solution/BaseSales/utils.js +22 -19
  25. package/dist/solution/BookingByStep/index.d.ts +1 -1
  26. package/dist/solution/BookingTicket/index.d.ts +1 -1
  27. package/dist/solution/ScanOrder/index.js +7 -5
  28. package/dist/solution/ScanOrder/types.d.ts +8 -5
  29. package/dist/solution/ScanOrder/types.js +2 -3
  30. package/dist/solution/ScanOrder/utils.d.ts +1 -1
  31. package/dist/solution/ScanOrder/utils.js +26 -23
  32. package/dist/solution/VenueBooking/index.js +5 -3
  33. package/dist/solution/VenueBooking/sales-section-4-annotated.json +0 -2
  34. package/lib/model/strategy/adapter/promotion/index.js +0 -49
  35. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +2 -1
  36. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
  37. package/lib/modules/Cart/utils/cartProduct.js +9 -2
  38. package/lib/modules/Order/index.d.ts +1 -3
  39. package/lib/modules/Order/index.js +45 -58
  40. package/lib/modules/Order/types.d.ts +9 -6
  41. package/lib/modules/Order/utils.d.ts +9 -2
  42. package/lib/modules/Order/utils.js +41 -10
  43. package/lib/modules/SalesSummary/types.d.ts +3 -1
  44. package/lib/modules/SalesSummary/utils.js +5 -3
  45. package/lib/server/modules/order/index.d.ts +126 -6
  46. package/lib/server/modules/order/index.js +722 -42
  47. package/lib/server/modules/order/types.d.ts +0 -2
  48. package/lib/server/modules/products/index.d.ts +90 -6
  49. package/lib/server/modules/products/index.js +492 -30
  50. package/lib/solution/BaseSales/index.js +14 -5
  51. package/lib/solution/BaseSales/types.d.ts +8 -5
  52. package/lib/solution/BaseSales/utils/cartPromotion.js +6 -6
  53. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
  54. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +21 -14
  55. package/lib/solution/BaseSales/utils.d.ts +1 -1
  56. package/lib/solution/BaseSales/utils.js +11 -7
  57. package/lib/solution/BookingByStep/index.d.ts +1 -1
  58. package/lib/solution/BookingTicket/index.d.ts +1 -1
  59. package/lib/solution/ScanOrder/index.js +4 -4
  60. package/lib/solution/ScanOrder/types.d.ts +8 -5
  61. package/lib/solution/ScanOrder/utils.d.ts +1 -1
  62. package/lib/solution/ScanOrder/utils.js +12 -8
  63. package/lib/solution/VenueBooking/index.js +2 -2
  64. package/lib/solution/VenueBooking/sales-section-4-annotated.json +0 -2
  65. package/package.json +1 -1
  66. package/dist/solution/Checkout/appointmentDemo.json +0 -1
  67. package/lib/solution/Checkout/appointmentDemo.json +0 -1
@@ -266,7 +266,16 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
266
266
  product_variant_id: product.product_variant_id ?? authoritativeProduct.product_variant_id ?? 0,
267
267
  num: product.num ?? product.quantity ?? authoritativeProduct.num,
268
268
  quantity: product.quantity ?? product.num ?? authoritativeProduct.quantity,
269
- product_option_item: product.product_option_item ?? authoritativeProduct.product_option_item,
269
+ product_sku: (() => {
270
+ const authoritativeSku = (0, import_utils.ensureProductSku)(authoritativeProduct);
271
+ const productSku = (0, import_utils.ensureProductSku)(product);
272
+ const hasProductSku = product.product_sku && typeof product.product_sku === "object";
273
+ return {
274
+ ...authoritativeSku,
275
+ ...productSku,
276
+ option: hasProductSku ? productSku.option : authoritativeSku.option
277
+ };
278
+ })(),
270
279
  product_bundle: productBundle,
271
280
  metadata: product.metadata ?? authoritativeProduct.metadata
272
281
  };
@@ -823,7 +832,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
823
832
  (sum, pd) => sum + Number(pd.amount || 0),
824
833
  0
825
834
  );
826
- const optionSum = (0, import_utils.sumOptionUnitPrice)(product.product_option_item);
835
+ const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product));
827
836
  const sourcePrice = ((_t = product.metadata) == null ? void 0 : _t.source_product_price) ?? (((_u = product.metadata) == null ? void 0 : _u.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
828
837
  const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
829
838
  const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
@@ -1002,7 +1011,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1002
1011
  (sum, pd) => sum + (pd.amount || 0),
1003
1012
  0
1004
1013
  );
1005
- const optionSum = (0, import_utils.sumOptionUnitPrice)(product.product_option_item);
1014
+ const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product));
1006
1015
  const sourcePrice = ((_h = product.metadata) == null ? void 0 : _h.source_product_price) ?? (((_i = product.metadata) == null ? void 0 : _i.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
1007
1016
  const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
1008
1017
  const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
@@ -1455,8 +1464,8 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1455
1464
  if (identity.unique_identification_number !== void 0) {
1456
1465
  params.unique_identification_number = identity.unique_identification_number;
1457
1466
  }
1458
- if (identity.product_option_item !== void 0) {
1459
- params.product_option_item = identity.product_option_item;
1467
+ if (identity.product_sku !== void 0) {
1468
+ params.product_sku = identity.product_sku;
1460
1469
  }
1461
1470
  if (identity.product_bundle !== void 0)
1462
1471
  params.product_bundle = identity.product_bundle;
@@ -41,16 +41,20 @@ export interface BaseSalesOrderProductIdentity {
41
41
  identity_key?: string;
42
42
  unique_identification_number?: string;
43
43
  /** 参与合并/匹配;与 remove 通配语义见 isSkuOnlyDeleteIdentity */
44
- product_option_item?: any[];
44
+ product_sku?: BaseSalesProductSku;
45
45
  product_bundle?: any[];
46
46
  }
47
+ export interface BaseSalesProductSku {
48
+ option: any[];
49
+ [key: string]: any;
50
+ }
47
51
  export interface BaseSalesUpdateOrderProductQuantityParams extends BaseSalesOrderProductIdentity {
48
52
  num: number;
49
53
  }
50
54
  export interface BaseSalesOrderProduct extends BaseSalesOrderProductIdentity {
51
55
  order_detail_id: number | null;
52
56
  num: number;
53
- product_option_item: any[];
57
+ product_sku: BaseSalesProductSku;
54
58
  /**
55
59
  * 券后 **行 composite 单价** = `metadata.main_product_selling_price`
56
60
  * + Σ((bundle.bundle_selling_price ?? bundle.price) × (bundle.num ?? 1))
@@ -96,9 +100,8 @@ export interface BaseSalesOrderProduct extends BaseSalesOrderProductIdentity {
96
100
  * 出站 payload 版本的商品行。
97
101
  *
98
102
  * 与 tempOrder 内部 `BaseSalesOrderProduct` 的字段差异:
99
- * - `product_option_item[*]`:内部为 `{ option_group_item_id, option_group_id, num, price, ... }`,
100
- * 出站保留 `{ option_group_item_id, option_group_id, num }`
101
- * (后端 checkout 协议;丢弃 `price` 等运行时辅助字段)。
103
+ * - `product_sku.option[*]`:内部直接维护统一 Sales 协议字段;
104
+ * 提交时仅规范 `add_price`,保留传入/恢复得到的展示字段。
102
105
  * - `product_bundle[*].option[*]`:同上重命名规则。
103
106
  *
104
107
  * 运行时(UI 显示、加购合并、指纹、持久化)与提交边界统一消费字段名
@@ -48,7 +48,7 @@ var import_utils = require("../../../modules/Order/utils");
48
48
  var import_utils2 = require("../../ScanOrder/utils");
49
49
  function getOrderProductBasePrice(product) {
50
50
  const metadata = (product == null ? void 0 : product.metadata) || {};
51
- const optionSum = (0, import_utils.sumOptionUnitPrice)(product == null ? void 0 : product.product_option_item).toNumber();
51
+ const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product)).toNumber();
52
52
  if (metadata.source_product_price !== void 0) {
53
53
  const v2 = Number(metadata.source_product_price);
54
54
  return Number.isFinite(v2) ? v2 : 0;
@@ -63,7 +63,7 @@ function getOrderProductBasePrice(product) {
63
63
  function getOrderProductOriginalPriceForPromotion(product) {
64
64
  var _a;
65
65
  const metadata = (product == null ? void 0 : product.metadata) || {};
66
- const optionSum = (0, import_utils.sumOptionUnitPrice)(product == null ? void 0 : product.product_option_item).toNumber();
66
+ const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product)).toNumber();
67
67
  if (metadata.main_product_original_price !== void 0 && metadata.main_product_original_price !== null && metadata.main_product_original_price !== "") {
68
68
  const v = Number(metadata.main_product_original_price) - optionSum;
69
69
  if (Number.isFinite(v) && v >= 0)
@@ -101,7 +101,7 @@ function updatePromotionDiscountList(item, promotionDiscount) {
101
101
  var X_ITEMS_FOR_Y_PRICE = "X_ITEMS_FOR_Y_PRICE";
102
102
  function applyPromoUnitPriceToLine(item, input) {
103
103
  const metadata = item.metadata || (item.metadata = {});
104
- const optionSum = (0, import_utils.sumOptionUnitPrice)(item.product_option_item).toNumber();
104
+ const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(item)).toNumber();
105
105
  const promoUnitPrice = new import_decimal.default(Number(input.promoUnitPrice) || 0).toDecimalPlaces(2).toFixed(2);
106
106
  const mainSelling = new import_decimal.default(Number(promoUnitPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
107
107
  const catalogSource = new import_decimal.default(input.originalBasePrice).toDecimalPlaces(2).toFixed(2);
@@ -169,7 +169,7 @@ function mergeIdenticalPromotionCartLines(products) {
169
169
  continue;
170
170
  }
171
171
  const fingerprint = (0, import_utils2.buildProductLineFingerprint)(
172
- line.product_option_item,
172
+ (0, import_utils.getProductSkuOptions)(line),
173
173
  line.product_bundle
174
174
  );
175
175
  const unitPrice = String(
@@ -340,7 +340,7 @@ function getProductBundleForEvaluator(product) {
340
340
  function buildConsolidateKeyForPromotion(item) {
341
341
  var _a;
342
342
  const fingerprint = (0, import_utils2.buildProductLineFingerprint)(
343
- item.product_option_item,
343
+ (0, import_utils.getProductSkuOptions)(item),
344
344
  item.product_bundle
345
345
  );
346
346
  const bookingUid = (item == null ? void 0 : item.booking_uid) ?? ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.booking_uid);
@@ -795,7 +795,7 @@ function processCartPromotion(list, evaluator, options) {
795
795
  strategyTitle: (_b = priced.strategyMetadata) == null ? void 0 : _b.name
796
796
  });
797
797
  } else {
798
- const optionSum = (0, import_utils.sumOptionUnitPrice)(newItem.product_option_item).toNumber();
798
+ const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(newItem)).toNumber();
799
799
  const sourceRestore = new import_decimal.default(originalBasePrice).toDecimalPlaces(2).toFixed(2);
800
800
  const mainRestore = new import_decimal.default(Number(sourceRestore) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
801
801
  metadata.source_product_price = sourceRestore;
@@ -23,6 +23,7 @@ export interface BaseProductDetailPayload {
23
23
  option?: BaseProductDetailOptionItem[];
24
24
  options?: BaseProductDetailOptionItem[];
25
25
  product_option_item?: BaseProductDetailOptionItem[];
26
+ product_sku?: Record<string, any>;
26
27
  bundle?: BaseProductDetailBundleItem[];
27
28
  product_bundle?: BaseProductDetailBundleItem[];
28
29
  unique?: string;
@@ -54,13 +54,15 @@ function normalizeOptionItems(optionItems) {
54
54
  if (!Array.isArray(optionItems))
55
55
  return [];
56
56
  return optionItems.map((optionItem) => {
57
- const optionGroupItemId = toNumber(optionItem == null ? void 0 : optionItem.id);
57
+ const optionGroupItemId = toNumber((optionItem == null ? void 0 : optionItem.option_group_item_id) ?? (optionItem == null ? void 0 : optionItem.id));
58
58
  const price = (optionItem == null ? void 0 : optionItem.price) ?? (optionItem == null ? void 0 : optionItem.add_price) ?? 0;
59
59
  return {
60
+ ...optionItem,
60
61
  option_group_item_id: optionGroupItemId,
61
62
  option_group_id: toNumber(optionItem == null ? void 0 : optionItem.option_group_id),
62
63
  num: toSafePositiveInt((optionItem == null ? void 0 : optionItem.num) ?? (optionItem == null ? void 0 : optionItem.quantity), 1),
63
- price: toNumber(price, 0)
64
+ add_price: toNumber(price, 0),
65
+ price: void 0
64
66
  };
65
67
  });
66
68
  }
@@ -89,7 +91,7 @@ function findVariantById(origin, variantId) {
89
91
  return variants.find((variant) => Number(variant == null ? void 0 : variant.id) === variantId) || null;
90
92
  }
91
93
  function transformBaseProductToOrderProduct(params) {
92
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
94
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
93
95
  const { payload, fallbackProductId = null } = params;
94
96
  if (!payload || typeof payload !== "object")
95
97
  return null;
@@ -118,8 +120,10 @@ function transformBaseProductToOrderProduct(params) {
118
120
  sourceProductPrice
119
121
  );
120
122
  const hasPriceOverride = payload.price_override !== void 0 && payload.price_override !== null && payload.price_override !== "";
121
- const productOptionItem = normalizeOptionItems(
122
- payload.option ?? payload.options ?? payload.product_option_item
123
+ const productOptionItem = (0, import_utils.normalizeProductSkuOptions)(
124
+ normalizeOptionItems(
125
+ ((_d = payload.product_sku) == null ? void 0 : _d.option) ?? payload.option ?? payload.options ?? payload.product_option_item
126
+ )
123
127
  );
124
128
  const productBundle = normalizeBundleItems(
125
129
  payload.bundle ?? payload.product_bundle,
@@ -129,19 +133,19 @@ function transformBaseProductToOrderProduct(params) {
129
133
  const resolvedQuantity = toSafePositiveInt(payload.quantity ?? payload.num, 1);
130
134
  const originTotal = (0, import_manualProductDiscount.resolveManualDiscountOriginTotal)({
131
135
  originTotal: payload.origin_total,
132
- extendOriginTotal: (_d = payload._extend) == null ? void 0 : _d.origin_total,
133
- originExtendOriginTotal: (_e = origin == null ? void 0 : origin._extend) == null ? void 0 : _e.origin_total,
134
- sourceExtendOriginTotal: (_f = sourceProduct == null ? void 0 : sourceProduct._extend) == null ? void 0 : _f.origin_total,
136
+ extendOriginTotal: (_e = payload._extend) == null ? void 0 : _e.origin_total,
137
+ originExtendOriginTotal: (_f = origin == null ? void 0 : origin._extend) == null ? void 0 : _f.origin_total,
138
+ sourceExtendOriginTotal: (_g = sourceProduct == null ? void 0 : sourceProduct._extend) == null ? void 0 : _g.origin_total,
135
139
  catalogUnitPrice: (origin == null ? void 0 : origin.base_price) ?? (origin == null ? void 0 : origin.price) ?? (sourceProduct == null ? void 0 : sourceProduct.base_price) ?? (sourceProduct == null ? void 0 : sourceProduct.price),
136
140
  quantity: resolvedQuantity
137
141
  });
138
142
  const sellingTotal = Number(
139
- payload.line_total ?? payload.total ?? ((_g = payload._extend) == null ? void 0 : _g.total) ?? lineCompositeTotal
143
+ payload.line_total ?? payload.total ?? ((_h = payload._extend) == null ? void 0 : _h.total) ?? lineCompositeTotal
140
144
  );
141
145
  const discountReason = (0, import_manualProductDiscount.resolveManualDiscountReasonFromSources)({
142
146
  discountReason: payload.discount_reason,
143
- extendDiscountReason: (_h = payload._extend) == null ? void 0 : _h.discount_reason,
144
- originExtendDiscountReason: (_i = origin == null ? void 0 : origin._extend) == null ? void 0 : _i.discount_reason
147
+ extendDiscountReason: (_i = payload._extend) == null ? void 0 : _i.discount_reason,
148
+ originExtendDiscountReason: (_j = origin == null ? void 0 : origin._extend) == null ? void 0 : _j.discount_reason
145
149
  });
146
150
  const lineOriginalPrice = hasPriceOverride && Number.isFinite(originTotal) ? toPriceString(originTotal) : lineCompositeTotal;
147
151
  const manualDiscountList = (0, import_manualProductDiscount.shouldBuildManualProductDiscount)({
@@ -155,8 +159,8 @@ function transformBaseProductToOrderProduct(params) {
155
159
  sellingTotal: Number.isFinite(sellingTotal) ? sellingTotal : Number(lineCompositeTotal),
156
160
  quantity: resolvedQuantity,
157
161
  message: discountReason,
158
- discountway: (_j = payload._extend) == null ? void 0 : _j.discountway,
159
- discount_per: (_k = payload._extend) == null ? void 0 : _k.discount_per
162
+ discountway: (_k = payload._extend) == null ? void 0 : _k.discountway,
163
+ discount_per: (_l = payload._extend) == null ? void 0 : _l.discount_per
160
164
  })
161
165
  ) : payload.discount_list || [];
162
166
  const optionSum = (0, import_utils.sumOptionUnitPrice)(productOptionItem).toNumber();
@@ -195,7 +199,10 @@ function transformBaseProductToOrderProduct(params) {
195
199
  product_variant_id: productVariantId,
196
200
  unique_identification_number: uniqueIdentificationNumber ? String(uniqueIdentificationNumber) : void 0,
197
201
  num: resolvedQuantity,
198
- product_option_item: productOptionItem,
202
+ product_sku: {
203
+ ...payload.product_sku && typeof payload.product_sku === "object" ? payload.product_sku : {},
204
+ option: productOptionItem
205
+ },
199
206
  product_bundle: productBundle,
200
207
  discount_list: manualDiscountList,
201
208
  // 折后行价由 normalizeOrderProduct 按 main + bundle 合成;手动改价时 bundle 已为分摊后单价
@@ -12,7 +12,7 @@ export declare function buildProductLineFingerprint(productOptionItem?: unknown,
12
12
  export declare function getSafeProductNum(num?: number): number;
13
13
  /**
14
14
  * removeProductFromOrder 仅传 SKU 时的通配 identity(对象上未声明选项键)。
15
- * 与显式 `product_option_item: []` 区分:后者只匹配「无选项」行。
15
+ * 与显式 `product_sku: { option: [] }` 区分:后者只匹配「无选项」行。
16
16
  */
17
17
  export declare function isSkuOnlyDeleteIdentity(x: BaseSalesOrderProductIdentity): boolean;
18
18
  /**
@@ -65,7 +65,7 @@ function buildProductLineFingerprint(productOptionItem, productBundle) {
65
65
  option_group_item_id: Number(item == null ? void 0 : item.option_group_item_id) || 0,
66
66
  option_group_id: Number(item == null ? void 0 : item.option_group_id) || 0,
67
67
  num: typeof (item == null ? void 0 : item.num) === "number" && !Number.isNaN(item.num) ? Math.max(1, Math.floor(item.num)) : 1,
68
- price: String((item == null ? void 0 : item.price) ?? "")
68
+ price: String((item == null ? void 0 : item.add_price) ?? (item == null ? void 0 : item.price) ?? "")
69
69
  })).sort((p, q) => {
70
70
  if (p.option_group_item_id !== q.option_group_item_id) {
71
71
  return p.option_group_item_id - q.option_group_item_id;
@@ -100,10 +100,10 @@ function getSafeProductNum(num) {
100
100
  function isSkuOnlyDeleteIdentity(x) {
101
101
  if (x.identity_key)
102
102
  return false;
103
- return !("product_option_item" in x) && !("product_bundle" in x);
103
+ return !("product_sku" in x) && !("product_bundle" in x);
104
104
  }
105
105
  function normalizeOrderProduct(product) {
106
- var _a, _b, _c, _d, _e, _f;
106
+ var _a, _b, _c, _d, _e, _f, _g;
107
107
  const metadata = { ...product.metadata || {} };
108
108
  const resolvedIdentityKey = ((_a = product.metadata) == null ? void 0 : _a.unique_identification_number) ? String(product.metadata.unique_identification_number) : product.unique_identification_number && String(product.unique_identification_number).length > 0 ? String(product.unique_identification_number) : product.identity_key && String(product.identity_key).length > 0 ? String(product.identity_key) : (0, import_utils.createUuidV4)();
109
109
  metadata.unique_identification_number = resolvedIdentityKey;
@@ -142,12 +142,16 @@ function normalizeOrderProduct(product) {
142
142
  price_type: item.price_type ?? item.custom_price_type ?? "",
143
143
  price_type_ext: item.price_type_ext ?? item.custom_price_type_ext ?? ""
144
144
  }));
145
- const normalizedOptions = product.product_option_item || [];
145
+ const normalizedOptions = (0, import_utils.normalizeProductSkuOptions)((_e = product.product_sku) == null ? void 0 : _e.option);
146
146
  const optionSum = (0, import_utils.sumOptionUnitPrice)(normalizedOptions);
147
+ const productSku = {
148
+ ...(0, import_utils.ensureProductSku)(product),
149
+ option: normalizedOptions
150
+ };
147
151
  const isV2 = metadata.price_schema_version === 2 || metadata.price_schema_version === "2";
148
152
  const variantId = Number(product.product_variant_id || 0);
149
- const variantList = variantId ? (_e = metadata == null ? void 0 : metadata.origin) == null ? void 0 : _e.variant : null;
150
- const variantPrice = Array.isArray(variantList) ? (_f = variantList.find((v) => Number(v == null ? void 0 : v.id) === variantId)) == null ? void 0 : _f.price : void 0;
153
+ const variantList = variantId ? (_f = metadata == null ? void 0 : metadata.origin) == null ? void 0 : _f.variant : null;
154
+ const variantPrice = Array.isArray(variantList) ? (_g = variantList.find((v) => Number(v == null ? void 0 : v.id) === variantId)) == null ? void 0 : _g.price : void 0;
151
155
  const resolvedSource = (() => {
152
156
  var _a2, _b2;
153
157
  if (metadata.source_product_price !== void 0) {
@@ -219,7 +223,7 @@ function normalizeOrderProduct(product) {
219
223
  product_id: product.product_id,
220
224
  num: getSafeProductNum(product.num),
221
225
  product_variant_id: product.product_variant_id,
222
- product_option_item: normalizedOptions,
226
+ product_sku: productSku,
223
227
  selling_price: composedSellingPrice,
224
228
  original_price: finalOriginalPrice,
225
229
  tax_fee: product.tax_fee || "0.00",
@@ -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 | 5 | 1 | 4 | 2 | 3 | 6;
314
+ weekNum: 0 | 2 | 1 | 5 | 3 | 4 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -279,7 +279,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
279
279
  * 获取当前的客户搜索条件
280
280
  * @returns 当前搜索条件
281
281
  */
282
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
282
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
283
283
  /**
284
284
  * 获取客户列表状态(包含滚动加载相关状态)
285
285
  * @returns 客户状态
@@ -751,7 +751,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
751
751
  (sum, pd) => sum + (pd.amount || 0),
752
752
  0
753
753
  );
754
- const optionSum = (0, import_utils2.sumOptionUnitPrice)(product.product_option_item);
754
+ const optionSum = (0, import_utils2.sumOptionUnitPrice)((0, import_utils2.getProductSkuOptions)(product));
755
755
  const sourcePrice = ((_d = product.metadata) == null ? void 0 : _d.source_product_price) ?? (((_e = product.metadata) == null ? void 0 : _e.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
756
756
  const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
757
757
  const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
@@ -899,7 +899,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
899
899
  original_price: originalPrice,
900
900
  payment_price: sellingPrice,
901
901
  is_charge_tax: ruleProduct.is_gst ?? 0,
902
- product_option_item: [],
902
+ product_sku: { option: [] },
903
903
  discount_list: [],
904
904
  product_bundle: [],
905
905
  booking_uid: bookingUuid,
@@ -1009,8 +1009,8 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1009
1009
  };
1010
1010
  if (identity.identity_key !== void 0)
1011
1011
  params.identity_key = identity.identity_key;
1012
- if (identity.product_option_item !== void 0) {
1013
- params.product_option_item = identity.product_option_item;
1012
+ if (identity.product_sku !== void 0) {
1013
+ params.product_sku = identity.product_sku;
1014
1014
  }
1015
1015
  if (identity.product_bundle !== void 0)
1016
1016
  params.product_bundle = identity.product_bundle;
@@ -33,13 +33,17 @@ export interface ScanOrderOrderProductIdentity {
33
33
  identity_key?: string;
34
34
  unique_identification_number?: string;
35
35
  /** 参与合并/匹配;与 remove 通配语义见 isSkuOnlyDeleteIdentity */
36
- product_option_item?: any[];
36
+ product_sku?: ScanOrderProductSku;
37
37
  product_bundle?: any[];
38
38
  }
39
+ export interface ScanOrderProductSku {
40
+ option: any[];
41
+ [key: string]: any;
42
+ }
39
43
  export interface ScanOrderOrderProduct extends ScanOrderOrderProductIdentity {
40
44
  order_detail_id: number | null;
41
45
  num: number;
42
- product_option_item: any[];
46
+ product_sku: ScanOrderProductSku;
43
47
  /**
44
48
  * 券后 **行 composite 单价** = `metadata.main_product_selling_price`
45
49
  * + Σ((bundle.bundle_selling_price ?? bundle.price) × (bundle.num ?? 1))
@@ -85,9 +89,8 @@ export interface ScanOrderOrderProduct extends ScanOrderOrderProductIdentity {
85
89
  * 出站 payload 版本的商品行。
86
90
  *
87
91
  * 与 tempOrder 内部 `ScanOrderOrderProduct` 的字段差异:
88
- * - `product_option_item[*]`:内部为 `{ option_group_item_id, option_group_id, num, price, ... }`,
89
- * 出站保留 `{ option_group_item_id, option_group_id, num }`
90
- * (后端 checkout 协议;丢弃 `price` 等运行时辅助字段)。
92
+ * - `product_sku.option[*]`:内部直接维护统一 Sales 协议字段;
93
+ * 提交时仅规范 `add_price`,保留传入/恢复得到的展示字段。
91
94
  * - `product_bundle[*].option[*]`:同上重命名规则。
92
95
  *
93
96
  * 运行时(UI 显示、加购合并、指纹、持久化)与提交边界统一消费字段名
@@ -88,7 +88,7 @@ export declare function attachItemRuleLimitsToTopLevelProducts<T>(productList: T
88
88
  export declare function buildProductLineFingerprint(productOptionItem?: unknown, productBundle?: unknown): string;
89
89
  /**
90
90
  * removeProductFromOrder 仅传 SKU 时的通配 identity(对象上未声明选项键)。
91
- * 与显式 `product_option_item: []` 区分:后者只匹配「无选项」行。
91
+ * 与显式 `product_sku: { option: [] }` 区分:后者只匹配「无选项」行。
92
92
  */
93
93
  export declare function isSkuOnlyDeleteIdentity(x: ScanOrderOrderProductIdentity): boolean;
94
94
  /**
@@ -353,7 +353,7 @@ function buildProductLineFingerprint(productOptionItem, productBundle) {
353
353
  option_group_item_id: Number(item == null ? void 0 : item.option_group_item_id) || 0,
354
354
  option_group_id: Number(item == null ? void 0 : item.option_group_id) || 0,
355
355
  num: typeof (item == null ? void 0 : item.num) === "number" && !Number.isNaN(item.num) ? Math.max(1, Math.floor(item.num)) : 1,
356
- price: String((item == null ? void 0 : item.price) ?? "")
356
+ price: String((item == null ? void 0 : item.add_price) ?? (item == null ? void 0 : item.price) ?? "")
357
357
  })).sort((p, q) => {
358
358
  if (p.option_group_item_id !== q.option_group_item_id) {
359
359
  return p.option_group_item_id - q.option_group_item_id;
@@ -381,11 +381,11 @@ function buildProductLineFingerprint(productOptionItem, productBundle) {
381
381
  function isSkuOnlyDeleteIdentity(x) {
382
382
  if (x.unique_identification_number || x.identity_key)
383
383
  return false;
384
- return !("product_option_item" in x) && !("product_bundle" in x);
384
+ return !("product_sku" in x) && !("product_bundle" in x);
385
385
  }
386
386
  function fingerprintForIdentityWithOptionKeys(x) {
387
387
  const row = x;
388
- const opts = "product_option_item" in row ? Array.isArray(row.product_option_item) ? row.product_option_item : [] : [];
388
+ const opts = "product_sku" in row ? (0, import_utils.getProductSkuOptions)(row) : [];
389
389
  const buds = "product_bundle" in row ? Array.isArray(row.product_bundle) ? row.product_bundle : [] : [];
390
390
  return buildProductLineFingerprint(opts, buds);
391
391
  }
@@ -407,7 +407,7 @@ function getProductIdentityIndex(products, identity) {
407
407
  return products.findIndex((item) => isIdentityMatch(item, identity));
408
408
  }
409
409
  function normalizeOrderProduct(product) {
410
- var _a, _b, _c, _d, _e, _f;
410
+ var _a, _b, _c, _d, _e, _f, _g;
411
411
  const metadata = { ...product.metadata || {} };
412
412
  const resolvedIdentityKey = ((_a = product.metadata) == null ? void 0 : _a.unique_identification_number) ? String(product.metadata.unique_identification_number) : product.unique_identification_number && String(product.unique_identification_number).length > 0 ? String(product.unique_identification_number) : product.identity_key && String(product.identity_key).length > 0 ? String(product.identity_key) : (0, import_utils.createUuidV4)();
413
413
  metadata.unique_identification_number = resolvedIdentityKey;
@@ -446,12 +446,16 @@ function normalizeOrderProduct(product) {
446
446
  price_type: item.price_type ?? item.custom_price_type ?? "",
447
447
  price_type_ext: item.price_type_ext ?? item.custom_price_type_ext ?? ""
448
448
  }));
449
- const normalizedOptions = product.product_option_item || [];
449
+ const normalizedOptions = (0, import_utils.normalizeProductSkuOptions)((_e = product.product_sku) == null ? void 0 : _e.option);
450
450
  const optionSum = (0, import_utils.sumOptionUnitPrice)(normalizedOptions);
451
+ const productSku = {
452
+ ...(0, import_utils.ensureProductSku)(product),
453
+ option: normalizedOptions
454
+ };
451
455
  const isV2 = metadata.price_schema_version === 2 || metadata.price_schema_version === "2";
452
456
  const variantId = Number(product.product_variant_id || 0);
453
- const variantList = variantId ? (_e = metadata == null ? void 0 : metadata.origin) == null ? void 0 : _e.variant : null;
454
- const variantPrice = Array.isArray(variantList) ? (_f = variantList.find((v) => Number(v == null ? void 0 : v.id) === variantId)) == null ? void 0 : _f.price : void 0;
457
+ const variantList = variantId ? (_f = metadata == null ? void 0 : metadata.origin) == null ? void 0 : _f.variant : null;
458
+ const variantPrice = Array.isArray(variantList) ? (_g = variantList.find((v) => Number(v == null ? void 0 : v.id) === variantId)) == null ? void 0 : _g.price : void 0;
455
459
  const resolvedSource = (() => {
456
460
  var _a2, _b2;
457
461
  if (metadata.source_product_price !== void 0) {
@@ -527,7 +531,7 @@ function normalizeOrderProduct(product) {
527
531
  product_id: product.product_id,
528
532
  num: getSafeProductNum(product.num),
529
533
  product_variant_id: product.product_variant_id,
530
- product_option_item: normalizedOptions,
534
+ product_sku: productSku,
531
535
  selling_price: composedSellingPrice,
532
536
  original_price: manualOriginalPrice,
533
537
  tax_fee: product.tax_fee || "0.00",
@@ -1077,7 +1077,7 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
1077
1077
  product_variant_id: 0,
1078
1078
  num: 1,
1079
1079
  product_bundle: [],
1080
- product_option_item: [],
1080
+ product_sku: { option: [] },
1081
1081
  discount_list: [],
1082
1082
  custom_deposit_data: customDepositData,
1083
1083
  metadata: {}
@@ -1348,7 +1348,7 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
1348
1348
  (sum, pd) => sum + (pd.amount || 0),
1349
1349
  0
1350
1350
  );
1351
- const optionSum = (0, import_utils3.sumOptionUnitPrice)(product.product_option_item);
1351
+ const optionSum = (0, import_utils3.sumOptionUnitPrice)((0, import_utils3.getProductSkuOptions)(product));
1352
1352
  const sourcePrice = ((_d = product.metadata) == null ? void 0 : _d.source_product_price) ?? (((_e = product.metadata) == null ? void 0 : _e.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
1353
1353
  const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
1354
1354
  const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
@@ -71,8 +71,6 @@
71
71
  "num__comment": "数量;int;↕;必填。统一使用 num,不再使用 product_quantity。",
72
72
  "product_variant_id": 0,
73
73
  "product_variant_id__comment": "多规格 ID;int;↕;可选。",
74
- "product_option_item": [],
75
- "product_option_item__comment": "选项配置;array;↕;可选。",
76
74
  "selling_price": "50.00",
77
75
  "selling_price__comment": "销售单价(交易快照);string;←;服务端返回,不能依赖基准数据回填。",
78
76
  "original_price": "60.00",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.2.190",
4
+ "version": "2.2.191",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -1 +0,0 @@
1
- {"type":"appointment_booking","platform":"PC","sales_channel":"my_pisel","order_sales_channel":"online_store","bookings":[{"id":0,"number":1,"registration_type":"all","relation_products":[],"is_all":false,"product":{"num":1,"product_id":61170,"product_variant_id":0,"product_bundle":[],"product_option_item":[],"discount_list":[{"amount":100,"type":"good_pass","discount":{"resource_id":64523,"title":{"auto":"玄-商品券","original":"玄-商品券","en":null,"zh-CN":null,"zh-HK":null},"original_amount":100,"product_id":61170,"percent":"1.00"}}]},"sub_type":"minutes","duration":480,"like_status":"common","resources":[{"relation_type":"form","like_status":"common","form_id":35,"relation_id":40357,"capacity":1,"metadata":{"combined_resource":{"status":1,"resource_ids":[40262,40263]},"form_name":"桌台","resource_name":"组合资源测试table-0422-01"},"children":[{"relation_type":"form","like_status":"common","id":40262,"main_field":"A01(组合资源-小桌-4 人)","resourceType":"single","form_id":35,"relation_id":40262,"capacity":1,"metadata":{"combined_resource":null,"form_name":"桌台","resource_name":"A01(组合资源-小桌-4 人)"}},{"relation_type":"form","like_status":"common","id":40263,"main_field":"A02(组合资源-小桌-4 人)","resourceType":"single","form_id":35,"relation_id":40263,"capacity":0,"metadata":{"combined_resource":null,"form_name":"桌台","resource_name":"A02(组合资源-小桌-4 人)"}}]},{"relation_type":"form","like_status":"common","form_id":214,"relation_id":38350,"capacity":1,"metadata":{"combined_resource":null,"form_name":"校区2","resource_name":"West Campus"}}],"schedule_id":0,"start_date":"2025-08-22","start_time":"09:00","select_date":"2025-08-22","end_time":"17:00","end_date":"2025-08-22","metadata":{"account":{"id":13433,"username":"a a"},"capacity":[{"id":0,"value":1,"name":""}]},"holder":null,"relation_forms":[]}],"shop_note":"","schedule_date":"2025-08-22 09:00:00","is_deposit":0,"relation_products":[],"relation_forms":[]}
@@ -1 +0,0 @@
1
- {"type":"appointment_booking","platform":"PC","sales_channel":"my_pisel","order_sales_channel":"online_store","bookings":[{"id":0,"number":1,"registration_type":"all","relation_products":[],"is_all":false,"product":{"num":1,"product_id":61170,"product_variant_id":0,"product_bundle":[],"product_option_item":[],"discount_list":[{"amount":100,"type":"good_pass","discount":{"resource_id":64523,"title":{"auto":"玄-商品券","original":"玄-商品券","en":null,"zh-CN":null,"zh-HK":null},"original_amount":100,"product_id":61170,"percent":"1.00"}}]},"sub_type":"minutes","duration":480,"like_status":"common","resources":[{"relation_type":"form","like_status":"common","form_id":35,"relation_id":40357,"capacity":1,"metadata":{"combined_resource":{"status":1,"resource_ids":[40262,40263]},"form_name":"桌台","resource_name":"组合资源测试table-0422-01"},"children":[{"relation_type":"form","like_status":"common","id":40262,"main_field":"A01(组合资源-小桌-4 人)","resourceType":"single","form_id":35,"relation_id":40262,"capacity":1,"metadata":{"combined_resource":null,"form_name":"桌台","resource_name":"A01(组合资源-小桌-4 人)"}},{"relation_type":"form","like_status":"common","id":40263,"main_field":"A02(组合资源-小桌-4 人)","resourceType":"single","form_id":35,"relation_id":40263,"capacity":0,"metadata":{"combined_resource":null,"form_name":"桌台","resource_name":"A02(组合资源-小桌-4 人)"}}]},{"relation_type":"form","like_status":"common","form_id":214,"relation_id":38350,"capacity":1,"metadata":{"combined_resource":null,"form_name":"校区2","resource_name":"West Campus"}}],"schedule_id":0,"start_date":"2025-08-22","start_time":"09:00","select_date":"2025-08-22","end_time":"17:00","end_date":"2025-08-22","metadata":{"account":{"id":13433,"username":"a a"},"capacity":[{"id":0,"value":1,"name":""}]},"holder":null,"relation_forms":[]}],"shop_note":"","schedule_date":"2025-08-22 09:00:00","is_deposit":0,"relation_products":[],"relation_forms":[]}