@pisell/pisellos 2.3.20 → 2.3.22

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 (35) hide show
  1. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +16 -10
  2. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
  3. package/dist/modules/Order/index.js +17 -7
  4. package/dist/modules/Order/types.d.ts +1 -0
  5. package/dist/modules/Order/utils.js +16 -4
  6. package/dist/server/index.d.ts +5 -0
  7. package/dist/server/index.js +428 -255
  8. package/dist/server/modules/order/types.d.ts +4 -0
  9. package/dist/server/modules/products/index.d.ts +5 -1
  10. package/dist/server/modules/products/index.js +383 -315
  11. package/dist/server/modules/products/types.d.ts +4 -0
  12. package/dist/solution/BaseSales/index.d.ts +10 -0
  13. package/dist/solution/BaseSales/index.js +503 -428
  14. package/dist/solution/BaseSales/types.d.ts +6 -1
  15. package/dist/solution/BaseSales/types.js +1 -1
  16. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -1
  17. package/dist/solution/BookingTicket/index.js +42 -24
  18. package/lib/model/strategy/adapter/promotion/index.js +49 -0
  19. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +5 -0
  20. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +1 -0
  21. package/lib/modules/Order/index.js +22 -7
  22. package/lib/modules/Order/types.d.ts +1 -0
  23. package/lib/modules/Order/utils.js +17 -3
  24. package/lib/server/index.d.ts +5 -0
  25. package/lib/server/index.js +121 -2
  26. package/lib/server/modules/order/types.d.ts +4 -0
  27. package/lib/server/modules/products/index.d.ts +5 -1
  28. package/lib/server/modules/products/index.js +20 -0
  29. package/lib/server/modules/products/types.d.ts +4 -0
  30. package/lib/solution/BaseSales/index.d.ts +10 -0
  31. package/lib/solution/BaseSales/index.js +66 -23
  32. package/lib/solution/BaseSales/types.d.ts +6 -1
  33. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +8 -0
  34. package/lib/solution/BookingTicket/index.js +15 -7
  35. package/package.json +1 -1
@@ -2,7 +2,7 @@ import { Module, PisellCore } from '../../../types';
2
2
  import { BaseModule } from '../../../modules/BaseModule';
3
3
  import { ProductData } from '../../../modules/Product/types';
4
4
  import type { RouteDefinition } from '../../types';
5
- import { ProductIdScope, ProductFormatter, ProductFormatterContext } from './types';
5
+ import { ProductIdScope, type ProductSnapshot, ProductFormatter, ProductFormatterContext } from './types';
6
6
  /**
7
7
  * Products 模块 - 用于获取和管理完整的商品详细数据
8
8
  * 相比 ProductList 模块,Products 会获取所有详细信息并缓存
@@ -185,6 +185,10 @@ export declare class ProductsModule extends BaseModule implements Module {
185
185
  * 获取商品列表(深拷贝,供外部安全使用)
186
186
  */
187
187
  getProducts(): Promise<ProductData[]>;
188
+ /**
189
+ * 批量获取商品轻量快照,供订单详情等响应补齐展示协议字段。
190
+ */
191
+ getProductSnapshotsByIds(ids: number[]): Promise<Record<string, ProductSnapshot>>;
188
192
  /**
189
193
  * 内部获取商品列表的直接引用(无拷贝)
190
194
  * 仅供内部 formatter 流程使用,因为 formatter 会创建新对象
@@ -860,6 +860,26 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
860
860
  (0, import_product.perfMark)("ProductsModule.getProducts(structuredClone)", performance.now() - t0, { count: result.length });
861
861
  return result;
862
862
  }
863
+ /**
864
+ * 批量获取商品轻量快照,供订单详情等响应补齐展示协议字段。
865
+ */
866
+ async getProductSnapshotsByIds(ids) {
867
+ const snapshots = {};
868
+ const seen = /* @__PURE__ */ new Set();
869
+ for (const id of ids) {
870
+ if (!Number.isFinite(id) || seen.has(id))
871
+ continue;
872
+ seen.add(id);
873
+ const product = this.store.map.get(id);
874
+ if (!product)
875
+ continue;
876
+ snapshots[String(id)] = {
877
+ cover: product.cover,
878
+ holder_config: product.holder_config
879
+ };
880
+ }
881
+ return snapshots;
882
+ }
863
883
  /**
864
884
  * 内部获取商品列表的直接引用(无拷贝)
865
885
  * 仅供内部 formatter 流程使用,因为 formatter 会创建新对象
@@ -28,6 +28,10 @@ export interface ProductIdScope {
28
28
  /** 指定商品集合 ID */
29
29
  collectionIds?: number[];
30
30
  }
31
+ export interface ProductSnapshot {
32
+ cover?: ProductData['cover'];
33
+ holder_config?: ProductData['holder_config'];
34
+ }
31
35
  /**
32
36
  * 加载报价单商品价格参数
33
37
  */
@@ -191,6 +191,16 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
191
191
  discountList: Discount[];
192
192
  }>;
193
193
  getDiscountList(): Discount[];
194
+ /** 读取 Discount 模块原始券列表(未经过 bookingTime 等过滤)。 */
195
+ getOriginalDiscountList(): Discount[];
196
+ /**
197
+ * 同步写入 Discount 模块的 discountList / originalDiscountList。
198
+ * 供 Holder 补全等场景在 OS store 层更新 machinecode holder 字段。
199
+ */
200
+ replaceDiscountStoreLists(params: {
201
+ discountList: Discount[];
202
+ originalDiscountList?: Discount[];
203
+ }): Promise<void>;
194
204
  scanPromotionCode(code: string, customerId?: number): Promise<BaseSalesScanCodeResult>;
195
205
  setDiscountSelected(params: {
196
206
  discountId: number;
@@ -102,7 +102,25 @@ function getBaseSalesMetadataUid(item, metadataKey) {
102
102
  return null;
103
103
  return String(uid);
104
104
  }
105
- function mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey) {
105
+ function isBaseSalesBlankValue(value) {
106
+ return value === void 0 || value === null || value === "";
107
+ }
108
+ function mergeBaseSalesProductSnapshotFields(currentItem, loadedItem) {
109
+ var _a, _b, _c;
110
+ const mergedItem = (0, import_lodash_es.cloneDeep)(loadedItem);
111
+ if (isBaseSalesBlankValue(mergedItem.product_cover) && !isBaseSalesBlankValue(currentItem == null ? void 0 : currentItem.product_cover)) {
112
+ mergedItem.product_cover = currentItem.product_cover;
113
+ }
114
+ const currentHolderConfig = (_a = currentItem == null ? void 0 : currentItem.metadata) == null ? void 0 : _a.holder_config;
115
+ if ((((_b = mergedItem.metadata) == null ? void 0 : _b.holder_config) === void 0 || ((_c = mergedItem.metadata) == null ? void 0 : _c.holder_config) === null) && currentHolderConfig !== void 0 && currentHolderConfig !== null) {
116
+ mergedItem.metadata = {
117
+ ...mergedItem.metadata || {},
118
+ holder_config: currentHolderConfig
119
+ };
120
+ }
121
+ return mergedItem;
122
+ }
123
+ function mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey, arrayKey) {
106
124
  const result = [];
107
125
  const indexByUid = /* @__PURE__ */ new Map();
108
126
  const appendOrReplaceByUid = (item) => {
@@ -114,7 +132,7 @@ function mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey) {
114
132
  }
115
133
  const existingIndex = indexByUid.get(uid);
116
134
  if (existingIndex !== void 0) {
117
- result[existingIndex] = clonedItem;
135
+ result[existingIndex] = arrayKey === "products" ? mergeBaseSalesProductSnapshotFields(result[existingIndex], clonedItem) : clonedItem;
118
136
  return;
119
137
  }
120
138
  indexByUid.set(uid, result.length);
@@ -134,7 +152,7 @@ function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord) {
134
152
  if (Array.isArray(currentValue) && Array.isArray(loadedValue)) {
135
153
  const metadataKey = getBaseSalesUniqueArrayMetadataKey(key);
136
154
  if (metadataKey) {
137
- return mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey);
155
+ return mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey, key);
138
156
  }
139
157
  return [
140
158
  ...(0, import_lodash_es.cloneDeep)(currentValue),
@@ -260,7 +278,10 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
260
278
  if (!this.store.order)
261
279
  return;
262
280
  this.serverOrderChangeHydrateInFlight = (async () => {
263
- const sales = await this.store.order.hydrateTempOrderFromRecord(changedOrder, {
281
+ var _a, _b;
282
+ const currentTempOrder = (_b = (_a = this.store.order).getTempOrder) == null ? void 0 : _b.call(_a);
283
+ const record = mergeSalesDetailRecordWithTempOrder(currentTempOrder, changedOrder);
284
+ const sales = await this.store.order.hydrateTempOrderFromRecord(record, {
264
285
  recalcOnHydrate: false
265
286
  });
266
287
  this.currentSalesDetail = sales;
@@ -1094,7 +1115,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1094
1115
  });
1095
1116
  }
1096
1117
  async loadDiscountConfig(params) {
1097
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
1118
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
1098
1119
  if (!this.store.order)
1099
1120
  throw new Error("order 模块未初始化");
1100
1121
  const tempOrder = this.store.order.ensureTempOrder();
@@ -1165,13 +1186,12 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1165
1186
  };
1166
1187
  }
1167
1188
  if (rulesModule) {
1168
- const holders = ((_l = tempOrder.holder) == null ? void 0 : _l.form_record) || [];
1169
- const orderTotalAmount = Number(((_m = orderStore.summary) == null ? void 0 : _m.total_amount) || 0);
1189
+ const orderTotalAmount = Number(((_l = orderStore.summary) == null ? void 0 : _l.total_amount) || 0);
1170
1190
  console.log("[BaseSales.applyDiscountConfig.calcDiscount]");
1171
1191
  const result = rulesModule.calcDiscount({
1172
1192
  productList: tempOrder.products,
1173
1193
  discountList: nextDiscountList,
1174
- holders,
1194
+ holders: [],
1175
1195
  isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product),
1176
1196
  orderTotalAmount
1177
1197
  }) || { productList: tempOrder.products, discountList: nextDiscountList };
@@ -1182,8 +1202,8 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1182
1202
  );
1183
1203
  }
1184
1204
  for (const product of tempOrder.products || []) {
1185
- const productUid = (_n = product.metadata) == null ? void 0 : _n.unique_identification_number;
1186
- const runtimeOrigin = productUid ? (_q = (_p = (_o = tempOrder._extend) == null ? void 0 : _o.productsByUid) == null ? void 0 : _p[productUid]) == null ? void 0 : _q.origin : void 0;
1205
+ const productUid = (_m = product.metadata) == null ? void 0 : _m.unique_identification_number;
1206
+ const runtimeOrigin = productUid ? (_p = (_o = (_n = tempOrder._extend) == null ? void 0 : _n.productsByUid) == null ? void 0 : _o[productUid]) == null ? void 0 : _p.origin : void 0;
1187
1207
  if ((runtimeOrigin == null ? void 0 : runtimeOrigin.isManualDiscount) || isBaseSalesManualProductDiscountProduct(product))
1188
1208
  continue;
1189
1209
  const totalPerUnitDiscount = (product.discount_list || []).reduce(
@@ -1191,7 +1211,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1191
1211
  0
1192
1212
  );
1193
1213
  const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product));
1194
- const sourcePrice = ((_r = product.metadata) == null ? void 0 : _r.source_product_price) ?? (((_s = product.metadata) == null ? void 0 : _s.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");
1214
+ const sourcePrice = ((_q = product.metadata) == null ? void 0 : _q.source_product_price) ?? (((_r = product.metadata) == null ? void 0 : _r.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");
1195
1215
  const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
1196
1216
  const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
1197
1217
  if (product.metadata) {
@@ -1227,7 +1247,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1227
1247
  };
1228
1248
  }
1229
1249
  async bestDiscount(cb) {
1230
- var _a, _b, _c, _d;
1250
+ var _a, _b, _c;
1231
1251
  if (!this.store.order)
1232
1252
  throw new Error("order 模块未初始化");
1233
1253
  const tempOrder = this.store.order.ensureTempOrder();
@@ -1246,13 +1266,12 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1246
1266
  };
1247
1267
  await (discountModule == null ? void 0 : discountModule.setDiscountList(nextDiscountList));
1248
1268
  if (rulesModule) {
1249
- const holders = ((_c = tempOrder.holder) == null ? void 0 : _c.form_record) || [];
1250
- const orderTotalAmount = Number(((_d = orderStore.summary) == null ? void 0 : _d.total_amount) || 0);
1269
+ const orderTotalAmount = Number(((_c = orderStore.summary) == null ? void 0 : _c.total_amount) || 0);
1251
1270
  console.log("[BaseSales.bestDiscount.calcDiscount]");
1252
1271
  result = rulesModule.calcDiscount({
1253
1272
  productList: tempOrder.products,
1254
1273
  discountList: nextDiscountList,
1255
- holders,
1274
+ holders: [],
1256
1275
  isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product),
1257
1276
  orderTotalAmount
1258
1277
  }) || result;
@@ -1286,6 +1305,30 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1286
1305
  return [];
1287
1306
  return this.store.order.getDiscountList();
1288
1307
  }
1308
+ /** 读取 Discount 模块原始券列表(未经过 bookingTime 等过滤)。 */
1309
+ getOriginalDiscountList() {
1310
+ var _a, _b;
1311
+ if (!this.store.order)
1312
+ return [];
1313
+ const discountModule = (_a = this.store.order.store) == null ? void 0 : _a.discount;
1314
+ return ((_b = discountModule == null ? void 0 : discountModule.getOriginalDiscountList) == null ? void 0 : _b.call(discountModule)) || [];
1315
+ }
1316
+ /**
1317
+ * 同步写入 Discount 模块的 discountList / originalDiscountList。
1318
+ * 供 Holder 补全等场景在 OS store 层更新 machinecode holder 字段。
1319
+ */
1320
+ async replaceDiscountStoreLists(params) {
1321
+ var _a;
1322
+ if (!this.store.order)
1323
+ throw new Error("order 模块未初始化");
1324
+ const discountModule = (_a = this.store.order.store) == null ? void 0 : _a.discount;
1325
+ if (!discountModule)
1326
+ return;
1327
+ if (params.originalDiscountList) {
1328
+ await discountModule.setOriginalDiscountList(params.originalDiscountList);
1329
+ }
1330
+ await discountModule.setDiscountList(params.discountList);
1331
+ }
1289
1332
  async scanPromotionCode(code, customerId) {
1290
1333
  try {
1291
1334
  if (!this.store.order)
@@ -1298,7 +1341,8 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1298
1341
  return {
1299
1342
  isAvailable: raw.isAvailable,
1300
1343
  type: raw.type,
1301
- unavailableReason: raw.unavailableReason
1344
+ unavailableReason: raw.unavailableReason,
1345
+ scannedDiscountList: raw.scannedDiscountList
1302
1346
  };
1303
1347
  } catch (error) {
1304
1348
  throw error;
@@ -1306,7 +1350,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1306
1350
  }
1307
1351
  // TODO 需要优化,这段逻辑太长了,里面应该有些历史遗留问题
1308
1352
  async setDiscountSelected(params) {
1309
- var _a, _b, _c, _d, _e, _f, _g, _h;
1353
+ var _a, _b, _c, _d, _e, _f, _g;
1310
1354
  try {
1311
1355
  if (!this.store.order)
1312
1356
  throw new Error("order 模块未初始化");
@@ -1323,17 +1367,16 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1323
1367
  const orderStore = this.store.order.store || {};
1324
1368
  const discountModule = orderStore.discount;
1325
1369
  const rulesModule = orderStore.rules;
1326
- const holders = ((_a = tempOrder.holder) == null ? void 0 : _a.form_record) || [];
1327
1370
  let nextDiscountList = updated;
1328
1371
  await (discountModule == null ? void 0 : discountModule.setDiscountList(updated));
1329
1372
  if (rulesModule) {
1330
- const orderTotalAmount = Number(((_b = orderStore.summary) == null ? void 0 : _b.total_amount) || 0);
1373
+ const orderTotalAmount = Number(((_a = orderStore.summary) == null ? void 0 : _a.total_amount) || 0);
1331
1374
  console.log("[BaseSales.setDiscountSelected.calcDiscount]");
1332
1375
  const result = rulesModule.calcDiscount(
1333
1376
  {
1334
1377
  productList: tempOrder.products,
1335
1378
  discountList: updated,
1336
- holders,
1379
+ holders: [],
1337
1380
  isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product),
1338
1381
  orderTotalAmount
1339
1382
  },
@@ -1373,8 +1416,8 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1373
1416
  return rid != null && selectedResourceIds.has(rid);
1374
1417
  });
1375
1418
  for (const product of tempOrder.products) {
1376
- const productUid = (_c = product.metadata) == null ? void 0 : _c.unique_identification_number;
1377
- const runtimeOrigin = productUid ? (_f = (_e = (_d = tempOrder._extend) == null ? void 0 : _d.productsByUid) == null ? void 0 : _e[productUid]) == null ? void 0 : _f.origin : void 0;
1419
+ const productUid = (_b = product.metadata) == null ? void 0 : _b.unique_identification_number;
1420
+ const runtimeOrigin = productUid ? (_e = (_d = (_c = tempOrder._extend) == null ? void 0 : _c.productsByUid) == null ? void 0 : _d[productUid]) == null ? void 0 : _e.origin : void 0;
1378
1421
  if ((runtimeOrigin == null ? void 0 : runtimeOrigin.isManualDiscount) || isBaseSalesManualProductDiscountProduct(product))
1379
1422
  continue;
1380
1423
  product.discount_list = filterSelectedDiscountDetails(product.discount_list);
@@ -1398,7 +1441,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1398
1441
  0
1399
1442
  );
1400
1443
  const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product));
1401
- const sourcePrice = ((_g = product.metadata) == null ? void 0 : _g.source_product_price) ?? (((_h = product.metadata) == null ? void 0 : _h.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");
1444
+ const sourcePrice = ((_f = product.metadata) == null ? void 0 : _f.source_product_price) ?? (((_g = product.metadata) == null ? void 0 : _g.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");
1402
1445
  const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
1403
1446
  const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
1404
1447
  if (product.metadata) {
@@ -1,3 +1,4 @@
1
+ import type { Discount } from '../../modules/Discount/types';
1
2
  import { OrderModule, ProductList, QuotationModule, SalesSummaryModule, ScanOrderLoggerModule as BaseSalesLoggerModule, ScheduleModule } from '../../modules';
2
3
  import type { ScanOrderLogInput as BaseSalesLogInput, ScanOrderLoggerProviderConfig as BaseSalesLoggerProviderConfig, ScanOrderLoggerProviderType as BaseSalesLoggerProviderType } from '../../modules/ScanOrderLogger/types';
3
4
  import type { QuantityCheckResult, QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
@@ -85,6 +86,8 @@ export interface BaseSalesOrderProduct extends BaseSalesOrderProductIdentity {
85
86
  booking_uid?: string;
86
87
  /** 多语言商品标题快照,随 tempOrder 提交到 checkout。 */
87
88
  product_title?: BaseSalesLocalizedText;
89
+ /** 商品封面图快照,随 tempOrder 提交到 checkout。 */
90
+ product_cover?: string;
88
91
  /**
89
92
  * 行级扩展 metadata。价格相关的权威字段:
90
93
  *
@@ -381,9 +384,11 @@ export interface BaseSalesLoggerRuntimeConfig {
381
384
  }
382
385
  export interface BaseSalesAddLogParams extends BaseSalesLogInput {
383
386
  }
384
- /** BaseSales.scanPromotionCode 对外的轻量结果(不含 discountList,UI resolve 后调 getDiscountList) */
387
+ /** BaseSales.scanPromotionCode 对外的轻量结果(UI 可用 getDiscountList scannedDiscountList 补 Holder) */
385
388
  export interface BaseSalesScanCodeResult {
386
389
  isAvailable: boolean;
387
390
  type?: 'server' | string;
388
391
  unavailableReason?: 'time_limit' | string;
392
+ /** batchSearch 原始结果;isAvailable=false 时 discountList 可能未写入 store,Holder 补全需读此字段 */
393
+ scannedDiscountList?: Discount[];
389
394
  }
@@ -50,6 +50,12 @@ function toPriceString(value, fallback = "0.00") {
50
50
  return fallback;
51
51
  return parsedValue.toFixed(2);
52
52
  }
53
+ function isBlankValue(value) {
54
+ return value === void 0 || value === null || typeof value === "string" && value.trim() === "";
55
+ }
56
+ function firstNonBlank(...values) {
57
+ return values.find((value) => !isBlankValue(value));
58
+ }
53
59
  function normalizeOptionItems(optionItems) {
54
60
  if (!Array.isArray(optionItems))
55
61
  return [];
@@ -198,6 +204,7 @@ function transformBaseProductToOrderProduct(params) {
198
204
  main_product_selling_price: mainProductSellingPrice,
199
205
  main_product_original_price: mainProductOriginalPrice,
200
206
  price_schema_version: 2,
207
+ holder_config: sourceProduct == null ? void 0 : sourceProduct.holder_config,
201
208
  ...hasPriceOverride ? {
202
209
  price_override: String(payload.price_override),
203
210
  is_manual_discount: 1
@@ -236,6 +243,7 @@ function transformBaseProductToOrderProduct(params) {
236
243
  metadata,
237
244
  note: payload.note != null ? String(payload.note) : "",
238
245
  product_title: productTitle,
246
+ product_cover: firstNonBlank(matchedVariant == null ? void 0 : matchedVariant.cover, sourceProduct == null ? void 0 : sourceProduct.cover),
239
247
  _origin: {
240
248
  ...sourceProduct || {},
241
249
  callbackData: payload
@@ -341,15 +341,21 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
341
341
  if (!this.store.order)
342
342
  throw new Error("order 模块未初始化");
343
343
  const raw = await this.store.order.scanCode(code, customerId);
344
+ const scannedList = raw.scannedDiscountList || [];
345
+ const extractedCustomerId = this.getDiscountCustomerId(scannedList);
346
+ const hasOrderCustomer = Boolean(this.store.order.getOrderCustomer());
347
+ if (!hasOrderCustomer && extractedCustomerId) {
348
+ await this.hydrateOrderCustomerFromScanDiscounts(scannedList);
349
+ }
344
350
  if (raw.isAvailable) {
345
- await this.hydrateOrderCustomerFromScanDiscounts(raw.scannedDiscountList || []);
346
351
  await this.store.order.recalculateSummary({ createIfMissing: true });
347
352
  this.store.order.persistTempOrder();
348
353
  }
349
354
  return {
350
355
  isAvailable: raw.isAvailable,
351
356
  type: raw.type,
352
- unavailableReason: raw.unavailableReason
357
+ unavailableReason: raw.unavailableReason,
358
+ scannedDiscountList: raw.scannedDiscountList
353
359
  };
354
360
  }
355
361
  async hydrateOrderCustomerFromScanDiscounts(discounts) {
@@ -366,11 +372,13 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
366
372
  this.setOrderCustomer(customer);
367
373
  }
368
374
  getDiscountCustomerId(discounts) {
369
- const discount = discounts.find((item) => item.customer_id != null);
370
- const customerId = Number(discount == null ? void 0 : discount.customer_id);
371
- if (!Number.isFinite(customerId) || customerId <= 0)
372
- return null;
373
- return customerId;
375
+ for (const item of discounts) {
376
+ const topLevelId = Number(item.customer_id);
377
+ if (Number.isFinite(topLevelId) && topLevelId > 0) {
378
+ return topLevelId;
379
+ }
380
+ }
381
+ return null;
374
382
  }
375
383
  async resolveCustomerByDiscountCustomerId(customerId) {
376
384
  var _a;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.3.20",
4
+ "version": "2.3.22",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",