@pisell/pisellos 0.0.337 → 0.0.339

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.
@@ -24,7 +24,7 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
24
24
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
25
25
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
26
26
  import { BaseModule } from "../BaseModule";
27
- import { uniqueById, getDiscountAmount } from "../../solution/ShopDiscount/utils";
27
+ import { uniqueById, getDiscountAmount, getDiscountListAmountTotal, getDiscountListAmount } from "../../solution/ShopDiscount/utils";
28
28
  import { getProductOriginTotalPrice, getProductTotalPrice } from "../Cart/utils";
29
29
  import Decimal from 'decimal.js';
30
30
  import { isBoolean } from 'lodash-es';
@@ -187,6 +187,55 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
187
187
  return !discount.isManualSelect;
188
188
  });
189
189
 
190
+ // 🔥 扁平化商品列表:将 bundle 子商品展开为虚拟商品
191
+ var flattenProductsWithBundle = function flattenProductsWithBundle(productList) {
192
+ var flattened = [];
193
+ productList.forEach(function (originProduct) {
194
+ var product = _this3.hooks.getProduct(originProduct);
195
+
196
+ // 1. 添加主商品
197
+ flattened.push({
198
+ type: 'main',
199
+ originProduct: originProduct,
200
+ product: product,
201
+ price: Number(product.price || 0),
202
+ id: product.id,
203
+ _id: product._id,
204
+ parentId: product._id,
205
+ quantity: product.quantity,
206
+ num: product.num
207
+ });
208
+
209
+ // 2. 展开 bundle 子商品
210
+ if (product.bundle && Array.isArray(product.bundle) && product.bundle.length > 0) {
211
+ product.bundle.forEach(function (bundleItem, bundleIndex) {
212
+ flattened.push({
213
+ type: 'bundle',
214
+ originProduct: originProduct,
215
+ parentProduct: product,
216
+ bundleItem: bundleItem,
217
+ bundleIndex: bundleIndex,
218
+ // 虚拟商品属性
219
+ price: Number(bundleItem.price || 0),
220
+ id: bundleItem._bundle_product_id,
221
+ // 🔥 使用 _bundle_product_id
222
+ _id: "".concat(product._id, "_bundle_").concat(bundleIndex),
223
+ parentId: product._id,
224
+ num: bundleItem.num || 1,
225
+ quantity: bundleItem.num || 1,
226
+ total: new Decimal(bundleItem.price || 0).mul(bundleItem.num || 1).toNumber(),
227
+ origin_total: new Decimal(bundleItem.price || 0).mul(bundleItem.num || 1).toNumber(),
228
+ original_price: bundleItem.original_price,
229
+ // 继承主商品属性
230
+ booking_id: product.booking_id,
231
+ discount_list: []
232
+ });
233
+ });
234
+ }
235
+ });
236
+ return flattened;
237
+ };
238
+
190
239
  // 优惠力度排序,传进来的数据里可能有商品券,也可能有优惠券
191
240
  // 1. 商品券(n.tag=good_pass)视为最优惠(免费)
192
241
  // 2. 折扣券(n.tag=product_discount_card)按照新的优先级排序:
@@ -222,12 +271,12 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
222
271
  }
223
272
  }
224
273
 
225
- // 3. 都是百分比时,折扣越大越优先(par_value越小越优先)
274
+ // 3. 都是百分比时,折扣越大越优先(par_value越大越优先)
226
275
  if (typeA === 'percent' && typeB === 'percent') {
227
276
  if (a.par_value !== b.par_value) {
228
277
  var _valueA = new Decimal(100).minus(a.par_value || 0);
229
278
  var _valueB = new Decimal(100).minus(b.par_value || 0);
230
- return _valueB.minus(_valueA).toNumber(); // 折扣大的在前
279
+ return _valueA.minus(_valueB).toNumber(); // 折扣大的在前
231
280
  }
232
281
  }
233
282
 
@@ -261,21 +310,50 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
261
310
  // }
262
311
  // })
263
312
 
313
+ // 🔥 扁平化商品列表(包含主商品和bundle子商品)
314
+ var flattenedList = flattenProductsWithBundle(productList);
315
+
316
+ // 对扁平化后的列表按价格降序排序(用于应用优惠券时优先选择高价商品)
317
+ var sortedFlattenedList = flattenedList.sort(function (a, b) {
318
+ var priceA = new Decimal(a.price || '0');
319
+ var priceB = new Decimal(b.price || '0');
320
+ if (priceA.equals(priceB)) {
321
+ // 价格相同时,主商品优先
322
+ if (a.type !== b.type) {
323
+ return a.type === 'main' ? -1 : 1;
324
+ }
325
+ // 都是主商品时,按原有逻辑排序
326
+ if (a.type === 'main' && b.type === 'main') {
327
+ if (a.product.quantity === b.product.quantity) {
328
+ var _b$product$discount_l, _a$product$discount_l;
329
+ return (((_b$product$discount_l = b.product.discount_list) === null || _b$product$discount_l === void 0 ? void 0 : _b$product$discount_l.length) || 0) - (((_a$product$discount_l = a.product.discount_list) === null || _a$product$discount_l === void 0 ? void 0 : _a$product$discount_l.length) || 0);
330
+ }
331
+ return a.product.quantity - b.product.quantity;
332
+ }
333
+ // 都是bundle时,按数量排序
334
+ if (a.type === 'bundle' && b.type === 'bundle') {
335
+ return (a.num || 1) - (b.num || 1);
336
+ }
337
+ }
338
+ return priceB.minus(priceA).toNumber();
339
+ });
340
+
341
+ /**
264
342
  // 对productList按价格降序排序(用于应用优惠券时优先选择高价商品) 价格相同时使用quantity 排序
265
- var sortedProductList = _toConsumableArray(productList).sort(function (a, b) {
266
- var aProduct = _this3.hooks.getProduct(a);
267
- var bProduct = _this3.hooks.getProduct(b);
268
- var priceA = new Decimal(aProduct.price || '0');
269
- var priceB = new Decimal(bProduct.price || '0');
343
+ const sortedProductList = [...productList].sort((a, b) => {
344
+ const aProduct = this.hooks.getProduct(a);
345
+ const bProduct = this.hooks.getProduct(b);
346
+ const priceA = new Decimal((aProduct.price as string) || '0');
347
+ const priceB = new Decimal((bProduct.price as string) || '0');
270
348
  if (priceA.toNumber() === priceB.toNumber()) {
271
349
  if (aProduct.quantity === bProduct.quantity) {
272
- var _bProduct$discount_li, _aProduct$discount_li;
273
- return ((_bProduct$discount_li = bProduct.discount_list) === null || _bProduct$discount_li === void 0 ? void 0 : _bProduct$discount_li.length) - ((_aProduct$discount_li = aProduct.discount_list) === null || _aProduct$discount_li === void 0 ? void 0 : _aProduct$discount_li.length);
350
+ return bProduct.discount_list?.length - aProduct.discount_list?.length;
274
351
  }
275
352
  return aProduct.quantity - bProduct.quantity;
276
353
  }
277
354
  return priceB.toNumber() - priceA.toNumber();
278
355
  });
356
+ */
279
357
 
280
358
  // 标记已使用的优惠券
281
359
  var usedDiscounts = new Map();
@@ -299,19 +377,39 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
299
377
  var appliedDiscountProducts = new Map();
300
378
 
301
379
  // 首先遍历所有商品和所有优惠券,确定每个优惠券的适用范围,包括isSelected为false的优惠券
302
- sortedProductList.forEach(function (originProduct) {
303
- var product = _this3.hooks.getProduct(originProduct);
380
+ // 🔥 使用扁平化后的列表,包含主商品和bundle子商品
381
+ sortedFlattenedList.forEach(function (flatItem) {
382
+ // 获取商品数据
383
+ var product, originProduct;
384
+ if (flatItem.type === 'main') {
385
+ product = flatItem.product;
386
+ originProduct = flatItem.originProduct;
387
+ } else {
388
+ // bundle子商品:构造虚拟商品对象
389
+ product = {
390
+ _id: flatItem._id,
391
+ id: flatItem.id,
392
+ price: flatItem.price,
393
+ quantity: flatItem.quantity,
394
+ num: flatItem.num,
395
+ total: flatItem.total,
396
+ origin_total: flatItem.origin_total,
397
+ booking_id: flatItem.booking_id,
398
+ discount_list: []
399
+ };
400
+ originProduct = flatItem.originProduct;
401
+ }
304
402
  addModeDiscount.forEach(function (discount) {
305
- var _product$discount_lis2, _product$discount_lis3;
403
+ var _product, _product2, _product3, _flatItem$bundleItem;
306
404
  var limitedData = discount === null || discount === void 0 ? void 0 : discount.limited_relation_product_data;
307
405
 
308
406
  // 是符合折扣的商品
309
407
  var isLimitedProduct = limitedData.type === 'product_all' || limitedData.product_ids && limitedData.product_ids.includes(product.id);
310
408
 
311
409
  // 编辑的商品 使用了优惠券不可用
312
- var isAvailableProduct = !(product !== null && product !== void 0 && product.booking_id && product !== null && product !== void 0 && (_product$discount_lis2 = product.discount_list) !== null && _product$discount_lis2 !== void 0 && _product$discount_lis2.length && product !== null && product !== void 0 && (_product$discount_lis3 = product.discount_list) !== null && _product$discount_lis3 !== void 0 && _product$discount_lis3.every(function (discount) {
410
+ var isAvailableProduct = flatItem.type === 'main' ? !((_product = product) !== null && _product !== void 0 && _product.booking_id && (_product2 = product) !== null && _product2 !== void 0 && (_product2 = _product2.discount_list) !== null && _product2 !== void 0 && _product2.length && (_product3 = product) !== null && _product3 !== void 0 && (_product3 = _product3.discount_list) !== null && _product3 !== void 0 && _product3.every(function (discount) {
313
411
  return discount.id && ['good_pass', 'discount_card', 'product_discount_card'].includes(discount.tag || discount.type);
314
- }));
412
+ })) : !(flatItem !== null && flatItem !== void 0 && flatItem.booking_id && flatItem !== null && flatItem !== void 0 && (_flatItem$bundleItem = flatItem.bundleItem) !== null && _flatItem$bundleItem !== void 0 && (_flatItem$bundleItem = _flatItem$bundleItem.metadata) !== null && _flatItem$bundleItem !== void 0 && _flatItem$bundleItem.custom_product_bundle_map_id);
315
413
 
316
414
  // 判断优惠券是否适用于该商品
317
415
  if (isAvailableProduct && isLimitedProduct) {
@@ -331,7 +429,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
331
429
  fixed_amount: product.price,
332
430
  resource_id: discount.id,
333
431
  title: discount.format_title,
334
- original_amount: product.origin_total,
432
+ original_amount: product.price || product.origin_total,
335
433
  pre_value: discount.par_value,
336
434
  product_id: originProduct.id
337
435
  }
@@ -346,27 +444,60 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
346
444
  }
347
445
  });
348
446
  });
349
- console.log(sortedProductList, 'sortedProductListsortedProductList');
447
+
448
+ // 🔥 用于存储扁平化商品处理结果的Map
449
+ var processedFlatItemsMap = new Map();
350
450
 
351
451
  // 然后再处理应用哪些优惠券,此时只考虑filteredDiscountList中的优惠券
352
- sortedProductList.forEach(function (originProduct, index) {
353
- var _product$discount_lis4, _product$discount_lis5, _product$discount_lis7, _product$discount_lis8, _product$discount_lis9, _product$discount_lis10, _product$discount_lis11;
354
- var product = _this3.hooks.getProduct(originProduct);
355
- if (product !== null && product !== void 0 && product.booking_id && (_product$discount_lis4 = product.discount_list) !== null && _product$discount_lis4 !== void 0 && _product$discount_lis4.length && product !== null && product !== void 0 && (_product$discount_lis5 = product.discount_list) !== null && _product$discount_lis5 !== void 0 && _product$discount_lis5.every(function (discount) {
452
+ // 🔥 使用扁平化后的列表进行处理
453
+ sortedFlattenedList.forEach(function (flatItem, index) {
454
+ var _product4, _product$discount_lis2, _product5, _product$discount_lis4, _product6, _product6$every, _product$discount_lis5, _product$discount_lis6;
455
+ // 获取商品数据
456
+ var product, originProduct;
457
+ if (flatItem.type === 'main') {
458
+ product = flatItem.product;
459
+ originProduct = flatItem.originProduct;
460
+ } else {
461
+ var _flatItem$bundleItem2, _flatItem$bundleItem3, _flatItem$bundleItem4;
462
+ // bundle子商品
463
+ product = {
464
+ _id: flatItem._id,
465
+ id: flatItem.id,
466
+ price: flatItem.price,
467
+ quantity: flatItem.quantity,
468
+ num: flatItem.num,
469
+ total: flatItem.total,
470
+ original_price: flatItem === null || flatItem === void 0 || (_flatItem$bundleItem2 = flatItem.bundleItem) === null || _flatItem$bundleItem2 === void 0 ? void 0 : _flatItem$bundleItem2.original_price,
471
+ origin_total: flatItem === null || flatItem === void 0 || (_flatItem$bundleItem3 = flatItem.bundleItem) === null || _flatItem$bundleItem3 === void 0 ? void 0 : _flatItem$bundleItem3.original_price,
472
+ booking_id: flatItem.booking_id,
473
+ discount_list: (flatItem === null || flatItem === void 0 || (_flatItem$bundleItem4 = flatItem.bundleItem) === null || _flatItem$bundleItem4 === void 0 ? void 0 : _flatItem$bundleItem4.discount_list) || []
474
+ };
475
+ originProduct = flatItem.originProduct;
476
+ }
477
+
478
+ // 已有优惠的商品跳过
479
+ if ((_product4 = product) !== null && _product4 !== void 0 && _product4.booking_id && (_product$discount_lis2 = product.discount_list) !== null && _product$discount_lis2 !== void 0 && _product$discount_lis2.length && (_product5 = product) !== null && _product5 !== void 0 && (_product5 = _product5.discount_list) !== null && _product5 !== void 0 && _product5.every(function (discount) {
356
480
  return discount.id && ['good_pass', 'discount_card', 'product_discount_card'].includes(discount.tag || discount.type);
357
481
  })) {
358
- processedProductsMap.set(product._id, [originProduct]);
482
+ if (flatItem.type === 'main') {
483
+ processedProductsMap.set(product._id, [originProduct]);
484
+ } else {
485
+ processedFlatItemsMap.set(flatItem._id, [_objectSpread(_objectSpread({}, flatItem), {}, {
486
+ processed: true
487
+ })]);
488
+ }
359
489
  return;
360
490
  }
361
491
 
362
492
  // 找到适用于此商品的所有优惠券,仅考虑isSelected不为false的优惠券
363
493
  var applicableDiscounts = sortedDiscountList.filter(function (discount) {
364
- var _product$discount_lis6;
494
+ var _product$discount_lis3;
365
495
  // 如果商品价格为 0,其实不需要使用任何优惠券,直接 return true
366
- // 商品券时主商品价格小于等于0不可用
367
- if ((Number(product.price) <= 0 || !product.price) && (discount.tag || discount.type) === 'good_pass') return false;
368
- // 折扣卡时总价小于等于0时不可用
369
- if ((Number(product.total) <= 0 || !product.total) && !((_product$discount_lis6 = product.discount_list) !== null && _product$discount_lis6 !== void 0 && _product$discount_lis6.find(function (n) {
496
+ // 商品券时主商品价格为0不可用
497
+ if ((Number(product.price) <= 0 || !product.price) && flatItem.type === 'main' && (discount.tag || discount.type) === 'good_pass') return false;
498
+
499
+ // 折扣卡时总价为0时不可用
500
+ if ((Number(product.total) <= 0 || !product.total) && !((_product$discount_lis3 = product.discount_list) !== null && _product$discount_lis3 !== void 0 && _product$discount_lis3.find(function (n) {
370
501
  var _n$discount;
371
502
  return ((_n$discount = n.discount) === null || _n$discount === void 0 ? void 0 : _n$discount.resource_id) === discount.id;
372
503
  })) && (discount.tag || discount.type) !== 'good_pass') return false;
@@ -377,8 +508,16 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
377
508
 
378
509
  // 判断优惠券是否适用于该商品
379
510
  if (limitedData.type === 'product_all') {
511
+ // 检查 package_sub_item_usage_rules
512
+ if (!_this3.checkPackageSubItemUsageRules(discount, flatItem)) {
513
+ return false;
514
+ }
380
515
  return true;
381
516
  } else if (limitedData.product_ids && limitedData.product_ids.includes(product.id)) {
517
+ // 检查 package_sub_item_usage_rules
518
+ if (!_this3.checkPackageSubItemUsageRules(discount, flatItem)) {
519
+ return false;
520
+ }
382
521
  return true;
383
522
  }
384
523
  return false;
@@ -393,18 +532,21 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
393
532
  var selectedDiscount = selectedDiscountCard || applicableDiscounts[0];
394
533
 
395
534
  // 如果是手动折扣,则不适用优惠券
396
- var isManualDiscount = typeof product.isManualDiscount === 'boolean' ? product.isManualDiscount : product.total != product.origin_total && (!((_product$discount_lis7 = product.discount_list) !== null && _product$discount_lis7 !== void 0 && _product$discount_lis7.length) || (product === null || product === void 0 || (_product$discount_lis8 = product.discount_list) === null || _product$discount_lis8 === void 0 || (_product$discount_lis9 = _product$discount_lis8.every) === null || _product$discount_lis9 === void 0 ? void 0 : _product$discount_lis9.call(_product$discount_lis8, function (item) {
535
+ var isManualDiscount = typeof product.isManualDiscount === 'boolean' ? product.isManualDiscount : product.total != product.origin_total && flatItem.type === 'main' && (product.bundle || []).every(function (item) {
536
+ var _ref3;
537
+ return !((_ref3 = item.discount_list || []) !== null && _ref3 !== void 0 && _ref3.length);
538
+ }) && (!((_product$discount_lis4 = product.discount_list) !== null && _product$discount_lis4 !== void 0 && _product$discount_lis4.length) || ((_product6 = product) === null || _product6 === void 0 || (_product6 = _product6.discount_list) === null || _product6 === void 0 || (_product6$every = _product6.every) === null || _product6$every === void 0 ? void 0 : _product6$every.call(_product6, function (item) {
397
539
  return item.type === 'product';
398
540
  })));
399
541
 
400
542
  // 勾选时覆盖手动折扣
401
- if (options !== null && options !== void 0 && options.discountId && (_product$discount_lis10 = product.discount_list) !== null && _product$discount_lis10 !== void 0 && _product$discount_lis10.some(function (item) {
543
+ if (options !== null && options !== void 0 && options.discountId && (_product$discount_lis5 = product.discount_list) !== null && _product$discount_lis5 !== void 0 && _product$discount_lis5.some(function (item) {
402
544
  var _item$discount;
403
545
  return ((_item$discount = item.discount) === null || _item$discount === void 0 ? void 0 : _item$discount.resource_id) === options.discountId;
404
546
  })) {
405
547
  isManualDiscount = false;
406
548
  }
407
- if (options !== null && options !== void 0 && options.selectedList && (_product$discount_lis11 = product.discount_list) !== null && _product$discount_lis11 !== void 0 && _product$discount_lis11.some(function (item) {
549
+ if (options !== null && options !== void 0 && options.selectedList && (_product$discount_lis6 = product.discount_list) !== null && _product$discount_lis6 !== void 0 && _product$discount_lis6.some(function (item) {
408
550
  var _options$selectedList;
409
551
  return options === null || options === void 0 || (_options$selectedList = options.selectedList) === null || _options$selectedList === void 0 ? void 0 : _options$selectedList.some(function (n) {
410
552
  var _item$discount2;
@@ -415,38 +557,47 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
415
557
  }
416
558
 
417
559
  // 如果没有适用的优惠券,或者手动折扣,则不适用优惠券
418
- // 自定义商品:如果未开启适用折扣卡(product.vouchersApplicable),则不适用优惠券
419
560
  if (applicableDiscounts.length === 0 || isManualDiscount || isBoolean(product.vouchersApplicable) && !product.vouchersApplicable) {
420
- if (product.isClient) {
421
- processedProductsMap.set(product._id, [_this3.hooks.setProduct(originProduct, _objectSpread(_objectSpread({}, isManualDiscount ? {} : {
422
- origin_total: getProductOriginTotalPrice({
423
- product: {
424
- original_price: product.original_price
425
- },
426
- bundle: product.bundle,
427
- options: product.options
428
- }),
429
- variant: originProduct._productInit.variant,
430
- original_price: originProduct._productInit.original_price,
431
- total: getProductTotalPrice({
432
- product: {
433
- price: product.price
434
- },
435
- bundle: product.bundle,
436
- options: product.options
437
- }),
438
- price: product.price
439
- }), {}, {
440
- discount_list: []
441
- }))]);
561
+ if (flatItem.type === 'main') {
562
+ // 主商品:保持原有逻辑
563
+ if (product.isClient) {
564
+ processedProductsMap.set(product._id, [_this3.hooks.setProduct(originProduct, _objectSpread(_objectSpread({}, isManualDiscount ? {} : {
565
+ origin_total: getProductOriginTotalPrice({
566
+ product: {
567
+ original_price: product.original_price
568
+ },
569
+ bundle: product.bundle,
570
+ options: product.options
571
+ }),
572
+ variant: originProduct._productInit.variant,
573
+ original_price: originProduct._productInit.original_price,
574
+ total: getProductTotalPrice({
575
+ product: {
576
+ price: product.price
577
+ },
578
+ bundle: product.bundle,
579
+ options: product.options
580
+ }),
581
+ price: product.price
582
+ }), {}, {
583
+ discount_list: []
584
+ }))]);
585
+ } else {
586
+ processedProductsMap.set(product._id, [_this3.hooks.setProduct(originProduct, _objectSpread(_objectSpread({}, isManualDiscount ? {} : {
587
+ _id: product._id.split('___')[0] + '___' + index,
588
+ total: product.origin_total || product.total,
589
+ price: product.price
590
+ }), {}, {
591
+ discount_list: []
592
+ }))]);
593
+ }
442
594
  } else {
443
- processedProductsMap.set(product._id, [_this3.hooks.setProduct(originProduct, _objectSpread(_objectSpread({}, isManualDiscount ? {} : {
444
- _id: product._id.split('___')[0] + '___' + index,
445
- total: product.origin_total || product.total,
446
- price: product.price
447
- }), {}, {
448
- discount_list: []
449
- }))]);
595
+ // bundle子商品:保存到扁平化Map
596
+ processedFlatItemsMap.set(flatItem._id, [_objectSpread(_objectSpread({}, flatItem), {}, {
597
+ discount_list: [],
598
+ price: flatItem.bundleItem.original_price,
599
+ processed: true
600
+ })]);
450
601
  }
451
602
  return;
452
603
  }
@@ -454,137 +605,547 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
454
605
  return;
455
606
  }
456
607
 
457
- // 是否需要拆分
608
+ // 是否需要拆分(商品券需要拆分)
458
609
  var isNeedSplit = (selectedDiscount.tag || selectedDiscount.type) === 'good_pass';
459
610
 
460
611
  // 需要拆分出来的数量
461
- var splitCount = isNeedSplit ? Math.min(product.quantity || product.num || 1, applicableDiscounts.filter(function (item) {
612
+ var totalQuantity = product.quantity || product.num || 1;
613
+ var availableGoodPassCount = applicableDiscounts.filter(function (item) {
462
614
  return (item.tag || item.type) === 'good_pass';
463
- }).length) : 1;
615
+ }).length;
616
+ var splitCount = isNeedSplit ? Math.min(product.quantity || product.num || 1, availableGoodPassCount) : 1;
464
617
  var arr = [];
465
- if (splitCount < product.quantity && isNeedSplit) {
466
- arr.push(_this3.hooks.setProduct(originProduct, {
467
- discount_list: [],
468
- quantity: product.quantity - splitCount,
469
- _id: product._id.split('___')[0]
470
- }));
471
- }
472
- for (var i = 0; i < splitCount; i++) {
473
- var _product$discount_lis12, _originProduct$_produ, _selectedDiscount$met;
474
- // 如果用过折扣卡,也就不存在拆分的情况了,这里直接使用上面计算出来的折扣卡
475
- var _selectedDiscount = selectedDiscountCard || applicableDiscounts[i];
476
- // 标记优惠券为已使用
477
- usedDiscounts.set(_selectedDiscount.id, true);
478
-
479
- // 记录实际应用了优惠券的商品信息
480
- var appliedProducts = appliedDiscountProducts.get(_selectedDiscount.id) || [];
481
-
482
- // 优先从 origin_total拿,可能会拿不到(比如用户端预约在没有配置 original_price 的情况下)
483
- var productOriginTotal = product.origin_total || product.total || 0;
484
- // 如果当前 product 有 discount_list,则先从 origin_total 拿
485
- if ((_product$discount_lis12 = product.discount_list) !== null && _product$discount_lis12 !== void 0 && _product$discount_lis12.length && product.origin_total) {
486
- productOriginTotal = product.origin_total;
487
- }
488
- // 如果originProduct?._productInit?.original_price为 0,product.origin_total可能为空,此时取 product.total
489
- if (Number((originProduct === null || originProduct === void 0 || (_originProduct$_produ = originProduct._productInit) === null || _originProduct$_produ === void 0 ? void 0 : _originProduct$_produ.original_price) || 0) > 0 && product.origin_total && product.total && product.origin_total !== product.total) {
490
- productOriginTotal = product.total;
618
+
619
+ // 🔥 主商品和bundle子商品分别处理
620
+ if (flatItem.type === 'main') {
621
+ // 主商品:保持原有逻辑
622
+ if (splitCount < totalQuantity && isNeedSplit) {
623
+ arr.push(_this3.hooks.setProduct(originProduct, {
624
+ discount_list: [],
625
+ quantity: totalQuantity - splitCount,
626
+ _id: product._id.split('___')[0]
627
+ }));
491
628
  }
629
+ for (var i = 0; i < splitCount; i++) {
630
+ var _product$discount_lis7, _originProduct, _selectedDiscount$met;
631
+ // 如果用过折扣卡,也就不存在拆分的情况了,这里直接使用上面计算出来的折扣卡
632
+ var _selectedDiscount = selectedDiscountCard || applicableDiscounts[i];
633
+ // 标记优惠券为已使用
634
+ usedDiscounts.set(_selectedDiscount.id, true);
492
635
 
493
- // 计算使用折扣卡/商品券以后,单个商品的总 total
494
- var targetProductTotal = getDiscountAmount(_selectedDiscount, productOriginTotal, product.price);
495
- var discountType = _selectedDiscount.tag === 'product_discount_card' ? 'discount_card' : _selectedDiscount.tag;
496
- var discountDetail = {
497
- amount: new Decimal(productOriginTotal).minus(new Decimal(targetProductTotal)).toNumber(),
498
- type: discountType,
499
- discount: {
500
- discount_card_type: _selectedDiscount === null || _selectedDiscount === void 0 || (_selectedDiscount$met = _selectedDiscount.metadata) === null || _selectedDiscount$met === void 0 ? void 0 : _selectedDiscount$met.discount_card_type,
501
- fixed_amount: new Decimal(productOriginTotal).minus(new Decimal(targetProductTotal)).toNumber(),
502
- resource_id: _selectedDiscount.id,
503
- title: _selectedDiscount.format_title,
504
- original_amount: productOriginTotal,
505
- product_id: originProduct.id,
506
- percent: _selectedDiscount.par_value
636
+ // 记录实际应用了优惠券的商品信息
637
+ var appliedProducts = appliedDiscountProducts.get(_selectedDiscount.id) || [];
638
+
639
+ // 优先从 origin_total拿,可能会拿不到(比如用户端预约在没有配置 original_price 的情况下)
640
+ var productOriginTotal = product.origin_total || product.total || 0;
641
+ // 如果当前 product 有 discount_list,则先从 origin_total 拿
642
+ if ((_product$discount_lis7 = product.discount_list) !== null && _product$discount_lis7 !== void 0 && _product$discount_lis7.length && product.origin_total) {
643
+ productOriginTotal = product.origin_total;
507
644
  }
508
- };
645
+ // 如果originProduct?._productInit?.original_price为 0,product.origin_total可能为空,此时取 product.total
646
+ if (Number(((_originProduct = originProduct) === null || _originProduct === void 0 || (_originProduct = _originProduct._productInit) === null || _originProduct === void 0 ? void 0 : _originProduct.original_price) || 0) > 0 && product.origin_total && product.total && product.origin_total !== product.total) {
647
+ productOriginTotal = product.total;
648
+ }
649
+
650
+ // 计算使用折扣卡/商品券以后,单个商品的总 total
651
+ var targetProductTotal = getDiscountAmount(_selectedDiscount, product.price, product.price);
652
+ var discountType = _selectedDiscount.tag === 'product_discount_card' ? 'discount_card' : _selectedDiscount.tag;
653
+ var discountDetail = {
654
+ amount: new Decimal(product.price).minus(new Decimal(targetProductTotal)).toNumber(),
655
+ type: discountType,
656
+ discount: {
657
+ discount_card_type: _selectedDiscount === null || _selectedDiscount === void 0 || (_selectedDiscount$met = _selectedDiscount.metadata) === null || _selectedDiscount$met === void 0 ? void 0 : _selectedDiscount$met.discount_card_type,
658
+ fixed_amount: new Decimal(product.price).minus(new Decimal(targetProductTotal)).toNumber(),
659
+ resource_id: _selectedDiscount.id,
660
+ title: _selectedDiscount.format_title,
661
+ original_amount: product.price,
662
+ product_id: originProduct.id,
663
+ percent: _selectedDiscount.par_value
664
+ }
665
+ };
509
666
 
510
- // 如果 discount.tag 或者 discount.type 是 good_pass,则不需要添加 num 属性
511
- if ((_selectedDiscount.tag || _selectedDiscount.type) !== 'good_pass') {
512
- discountDetail.num = product.num || 1;
667
+ // 如果 discount.tag 或者 discount.type 是 good_pass,则不需要添加 num 属性
668
+ if ((_selectedDiscount.tag || _selectedDiscount.type) !== 'good_pass') {
669
+ discountDetail.num = product.num || 1;
670
+ }
671
+ appliedProducts.push(discountDetail);
672
+ appliedDiscountProducts.set(_selectedDiscount.id, appliedProducts);
673
+
674
+ // 记录应用了优惠券的商品
675
+ // 后续更新价格改为 getProductTotalPrice getProductOriginTotalPrice逻辑
676
+ if (product.isClient) {
677
+ arr.push(_this3.hooks.setProduct(originProduct, {
678
+ discount_list: [discountDetail],
679
+ price: _selectedDiscount.tag === 'good_pass' ? 0 : product.price,
680
+ quantity: isNeedSplit ? 1 : product.quantity,
681
+ origin_total: getProductOriginTotalPrice({
682
+ product: {
683
+ original_price: product.original_price
684
+ },
685
+ bundle: product.bundle,
686
+ options: product.options
687
+ }),
688
+ variant: originProduct._productInit.variant,
689
+ original_price: new Decimal(product.price || 0).toNumber(),
690
+ total: targetProductTotal
691
+ }));
692
+ } else {
693
+ arr.push(_this3.hooks.setProduct(originProduct, {
694
+ discount_list: [discountDetail],
695
+ _id: product._id.split('___')[0] + "___" + _selectedDiscount.id + index,
696
+ price: _selectedDiscount.tag === 'good_pass' ? 0 : product.price,
697
+ quantity: isNeedSplit ? 1 : product.quantity,
698
+ total: targetProductTotal,
699
+ origin_total: productOriginTotal
700
+ }));
701
+ }
513
702
  }
514
- appliedProducts.push(discountDetail);
515
- appliedDiscountProducts.set(_selectedDiscount.id, appliedProducts);
703
+ processedProductsMap.set(product._id, arr);
704
+ } else {
705
+ // 🔥 bundle子商品:支持拆分
706
+ var processedItems = [];
707
+ if (isNeedSplit) {
708
+ // 商品券:需要拆分数量
709
+ var discountNum = splitCount;
710
+ var normalNum = totalQuantity - discountNum;
516
711
 
517
- // 记录应用了优惠券的商品
518
- // 后续更新价格改为 getProductTotalPrice getProductOriginTotalPrice逻辑
519
- if (product.isClient) {
520
- arr.push(_this3.hooks.setProduct(originProduct, {
521
- discount_list: [discountDetail],
522
- price: _selectedDiscount.tag === 'good_pass' ? 0 : product.price,
523
- quantity: isNeedSplit ? 1 : product.quantity,
524
- origin_total: getProductOriginTotalPrice({
525
- product: {
526
- original_price: product.original_price
712
+ // 生成有折扣的商品(每张商品券对应 num: 1)
713
+ for (var _i = 0; _i < discountNum; _i++) {
714
+ var _selectedDiscount2 = applicableDiscounts[_i];
715
+ usedDiscounts.set(_selectedDiscount2.id, true);
716
+
717
+ // 🔥 生成唯一的 _id
718
+ var uniqueId = "".concat(flatItem._id, "_split_").concat(_i);
719
+ var _discountDetail = {
720
+ amount: product.origin_total,
721
+ type: 'good_pass',
722
+ discount: {
723
+ resource_id: _selectedDiscount2.id,
724
+ title: _selectedDiscount2.format_title,
725
+ original_amount: product.origin_total,
726
+ product_id: product.id
527
727
  },
528
- bundle: product.bundle,
529
- options: product.options
530
- }),
531
- variant: originProduct._productInit.variant,
532
- original_price: new Decimal(product.price || 0).toNumber(),
533
- total: targetProductTotal
534
- }));
728
+ metadata: {
729
+ // 🔥 使用拆分后的唯一 _id
730
+ custom_product_bundle_map_id: uniqueId,
731
+ num: 1
732
+ },
733
+ num: 1
734
+ };
735
+
736
+ // 记录实际应用的折扣
737
+ var _appliedProducts = appliedDiscountProducts.get(_selectedDiscount2.id) || [];
738
+ _appliedProducts.push(_discountDetail);
739
+ appliedDiscountProducts.set(_selectedDiscount2.id, _appliedProducts);
740
+ processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
741
+ // 🔥 使用唯一的 _id
742
+ _id: uniqueId,
743
+ num: 1,
744
+ quantity: 1,
745
+ price: 0,
746
+ // 商品券价格为0
747
+ total: 0,
748
+ discount_list: [_discountDetail],
749
+ processed: true,
750
+ _discountId: _selectedDiscount2.id
751
+ }));
752
+ }
753
+
754
+ // 生成无折扣的商品(剩余数量)
755
+ if (normalNum > 0) {
756
+ processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
757
+ // 🔥 为剩余商品生成唯一的 _id
758
+ _id: "".concat(flatItem._id, "_split_rest"),
759
+ num: normalNum,
760
+ quantity: normalNum,
761
+ discount_list: [],
762
+ processed: true
763
+ }));
764
+ }
535
765
  } else {
536
- arr.push(_this3.hooks.setProduct(originProduct, {
537
- discount_list: [discountDetail],
538
- _id: product._id.split('___')[0] + "___" + _selectedDiscount.id + "___" + index,
539
- price: _selectedDiscount.tag === 'good_pass' ? 0 : product.price,
540
- quantity: isNeedSplit ? 1 : product.quantity,
541
- total: targetProductTotal,
542
- origin_total: productOriginTotal
766
+ var _selectedDiscount3$me;
767
+ // 折扣卡:不拆分数量,直接应用
768
+ var _selectedDiscount3 = selectedDiscountCard || applicableDiscounts[0];
769
+ usedDiscounts.set(_selectedDiscount3.id, true);
770
+ var _productOriginTotal = product.original_price || product.price || 0;
771
+ var _targetProductTotal = getDiscountAmount(_selectedDiscount3, _productOriginTotal, _productOriginTotal);
772
+
773
+ // 🔥 使用当前的 _id 作为唯一标识
774
+ var _uniqueId = flatItem._id;
775
+ var _discountDetail2 = {
776
+ amount: new Decimal(_productOriginTotal).minus(_targetProductTotal).toNumber(),
777
+ type: _selectedDiscount3.tag === 'product_discount_card' ? 'discount_card' : _selectedDiscount3.tag,
778
+ discount: {
779
+ discount_card_type: _selectedDiscount3 === null || _selectedDiscount3 === void 0 || (_selectedDiscount3$me = _selectedDiscount3.metadata) === null || _selectedDiscount3$me === void 0 ? void 0 : _selectedDiscount3$me.discount_card_type,
780
+ fixed_amount: new Decimal(_productOriginTotal).minus(_targetProductTotal).toNumber(),
781
+ resource_id: _selectedDiscount3.id,
782
+ title: _selectedDiscount3.format_title,
783
+ original_amount: product.original_price,
784
+ product_id: product.id,
785
+ percent: _selectedDiscount3.par_value
786
+ },
787
+ metadata: {
788
+ // 🔥 使用唯一的 _id
789
+ custom_product_bundle_map_id: _uniqueId,
790
+ num: product.num || 1
791
+ },
792
+ num: product.num || 1
793
+ };
794
+
795
+ // 记录实际应用的折扣
796
+ var _appliedProducts2 = appliedDiscountProducts.get(_selectedDiscount3.id) || [];
797
+ _appliedProducts2.push(_discountDetail2);
798
+ appliedDiscountProducts.set(_selectedDiscount3.id, _appliedProducts2);
799
+ processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
800
+ total: _targetProductTotal,
801
+ price: new Decimal(_productOriginTotal || 0).minus(_discountDetail2.amount).toNumber(),
802
+ discount_list: [_discountDetail2],
803
+ processed: true
543
804
  }));
544
805
  }
806
+ processedFlatItemsMap.set(flatItem._id, processedItems);
545
807
  }
546
- console.log(arr, 'arrarrarr');
547
- processedProductsMap.set(product._id, arr);
548
808
  });
549
809
 
550
- // 按原始顺序构建处理后的商品列表
551
- var processedProductList = [];
552
- productList.forEach(function (originProduct) {
553
- var product = _this3.hooks.getProduct(originProduct);
554
- var getDefaultProduct = function getDefaultProduct() {
555
- if (product.isClient) {
556
- return _this3.hooks.setProduct(originProduct, {
557
- discount_list: [],
558
- price: product.price,
559
- origin_total: getProductOriginTotalPrice({
560
- product: {
561
- original_price: product.original_price
562
- },
563
- bundle: product.bundle,
564
- options: product.options
565
- }),
566
- variant: originProduct._productInit.variant,
567
- original_price: originProduct._productInit.original_price,
568
- total: getProductTotalPrice({
569
- product: {
810
+ // 🔥 重组:将处理后的bundle子商品重新组装回主商品
811
+ var reconstructProductsWithBundle = function reconstructProductsWithBundle(processedProductsMap, processedFlatItemsMap, originalProductList) {
812
+ var result = [];
813
+ originalProductList.forEach(function (originProduct) {
814
+ var product = _this3.hooks.getProduct(originProduct);
815
+
816
+ // 获取主商品处理结果
817
+ var mainProductArr = processedProductsMap.get(product._id);
818
+ if (!mainProductArr || mainProductArr.length === 0) {
819
+ // 如果没有处理结果,返回默认商品
820
+ var getDefaultProduct = function getDefaultProduct() {
821
+ if (product.isClient) {
822
+ return _this3.hooks.setProduct(originProduct, {
823
+ discount_list: [],
824
+ price: product.price,
825
+ origin_total: getProductOriginTotalPrice({
826
+ product: {
827
+ original_price: product.original_price
828
+ },
829
+ bundle: product.bundle,
830
+ options: product.options
831
+ }),
832
+ variant: originProduct._productInit.variant,
833
+ original_price: originProduct._productInit.original_price,
834
+ total: getProductTotalPrice({
835
+ product: {
836
+ price: product.price
837
+ },
838
+ bundle: product.bundle,
839
+ options: product.options
840
+ })
841
+ });
842
+ } else {
843
+ return _this3.hooks.setProduct(originProduct, {
844
+ discount_list: [],
845
+ total: product.total,
846
+ origin_total: product.origin_total,
570
847
  price: product.price
571
- },
572
- bundle: product.bundle,
573
- options: product.options
574
- })
575
- });
848
+ });
849
+ }
850
+ };
851
+ result.push(getDefaultProduct());
852
+ return;
853
+ }
854
+
855
+ // 检查是否有bundle子商品需要重组
856
+ var hasBundle = product.bundle && Array.isArray(product.bundle) && product.bundle.length > 0;
857
+ if (!hasBundle) {
858
+ // 没有bundle,直接使用主商品处理结果
859
+ result.push.apply(result, _toConsumableArray(mainProductArr));
576
860
  } else {
577
- return _this3.hooks.setProduct(originProduct, {
578
- discount_list: [],
579
- total: product.total,
580
- origin_total: product.origin_total,
581
- price: product.price
582
- });
861
+ // 🔥 有bundle,需要检查子商品是否应用了商品券
862
+ // 1. 先收集所有bundle子商品的处理结果
863
+ var bundleProcessingInfo = new Map();
864
+ var hasGoodPassApplied = false; // 标记是否有子商品应用了商品券
865
+
866
+ if (product.bundle && Array.isArray(product.bundle)) {
867
+ product.bundle.forEach(function (bundleItem, bundleIndex) {
868
+ var bundleItemId = "".concat(product._id, "_bundle_").concat(bundleIndex);
869
+ var processedBundleItems = processedFlatItemsMap.get(bundleItemId);
870
+ if (!processedBundleItems || processedBundleItems.length === 0) {
871
+ // 未处理的bundle item,保持原样
872
+ bundleProcessingInfo.set(bundleIndex, [bundleItem]);
873
+ } else {
874
+ // 处理过的bundle item
875
+ bundleProcessingInfo.set(bundleIndex, processedBundleItems);
876
+ // 🔥 检查是否应用了商品券(good_pass)
877
+ var hasGoodPass = processedBundleItems.some(function (item) {
878
+ var _item$discount_list;
879
+ return (_item$discount_list = item.discount_list) === null || _item$discount_list === void 0 ? void 0 : _item$discount_list.some(function (discount) {
880
+ return discount.type === 'good_pass' || discount.tag === 'good_pass';
881
+ });
882
+ });
883
+ if (hasGoodPass) {
884
+ hasGoodPassApplied = true;
885
+ }
886
+ }
887
+ });
888
+ }
889
+
890
+ // 🔥 2. 如果有子商品应用了商品券,且主商品数量大于1,需要拆分主商品
891
+ var mainProductQuantity = mainProductArr[0] ? _this3.hooks.getProduct(mainProductArr[0]).quantity : 1;
892
+ if (hasGoodPassApplied && mainProductArr.length === 1 && mainProductQuantity > 1) {
893
+ var mainProduct = mainProductArr[0];
894
+ var mainProductData = _this3.hooks.getProduct(mainProduct);
895
+
896
+ // 🔥 方案:拆分成2个主商品
897
+ // 1. 一个主商品(qty=1)包含拆分后的bundle
898
+ // 2. 一个主商品(qty=原quantity-1)包含原始未拆分的bundle
899
+
900
+ // 第一个:包含拆分后的bundle (qty=1)
901
+ var newBundleWithDiscount = [];
902
+ (product.bundle || []).forEach(function (bundleItem, bundleIndex) {
903
+ var processedItems = bundleProcessingInfo.get(bundleIndex) || [bundleItem];
904
+ if (processedItems.length > 1) {
905
+ // 被拆分的子商品,添加所有拆分项
906
+ processedItems.forEach(function (item) {
907
+ // 🔥 更新 discount_list 中的 num,使其与拆分后的 item.num 一致
908
+ var updatedDiscountList = (item.discount_list || []).map(function (discount) {
909
+ return _objectSpread(_objectSpread({}, discount), {}, {
910
+ num: item.num // 使用拆分后的 num
911
+ });
912
+ });
913
+ newBundleWithDiscount.push(_objectSpread(_objectSpread({}, bundleItem), {}, {
914
+ _id: item._id,
915
+ product_id: bundleItem.product_id,
916
+ price: item.price,
917
+ num: item.num,
918
+ discount_list: updatedDiscountList
919
+ }));
920
+ });
921
+ } else {
922
+ // 未拆分的子商品,保持原样
923
+ var item = processedItems[0];
924
+ if (item.processed) {
925
+ // 🔥 同样需要更新 discount_list 中的 num
926
+ var _updatedDiscountList = (item.discount_list || []).map(function (discount) {
927
+ return _objectSpread(_objectSpread({}, discount), {}, {
928
+ num: item.num // 使用当前的 num
929
+ });
930
+ });
931
+ newBundleWithDiscount.push(_objectSpread(_objectSpread({}, bundleItem), {}, {
932
+ _id: item._id,
933
+ product_id: bundleItem.product_id,
934
+ price: item.price,
935
+ num: item.num,
936
+ discount_list: _updatedDiscountList
937
+ }));
938
+ } else {
939
+ newBundleWithDiscount.push(item);
940
+ }
941
+ }
942
+ });
943
+
944
+ // 计算第一个主商品的总价(包含拆分后的bundle)
945
+ var newTotalWithDiscount = Number(mainProductData.price || 0);
946
+ var newOriginTotalWithDiscount = Number(mainProductData.original_price || mainProductData.price || 0);
947
+ if (newBundleWithDiscount.length > 0) {
948
+ newBundleWithDiscount.forEach(function (item) {
949
+ newTotalWithDiscount += Number(item.price) * Number(item.num);
950
+ });
951
+ newBundleWithDiscount.forEach(function (item) {
952
+ var _item$discount_list2;
953
+ var originalPrice = ((_item$discount_list2 = item.discount_list) === null || _item$discount_list2 === void 0 || (_item$discount_list2 = _item$discount_list2[0]) === null || _item$discount_list2 === void 0 || (_item$discount_list2 = _item$discount_list2.discount) === null || _item$discount_list2 === void 0 ? void 0 : _item$discount_list2.original_amount) || item.price;
954
+ newOriginTotalWithDiscount += Number(originalPrice) * Number(item.num);
955
+ });
956
+ }
957
+
958
+ // 🔥 更新主商品自己的 discount_list 中的 num(quantity=1)
959
+ var updatedMainDiscountList = mainProductData.discount_list.map(function (discount) {
960
+ var _discount$metadata2;
961
+ if (discount !== null && discount !== void 0 && (_discount$metadata2 = discount.metadata) !== null && _discount$metadata2 !== void 0 && _discount$metadata2.custom_product_bundle_map_id) {
962
+ // bundle的discount_list保持不变
963
+ return discount;
964
+ }
965
+ // 主商品自己的discount,更新num为1
966
+ return _objectSpread(_objectSpread({}, discount), {}, {
967
+ num: 1
968
+ });
969
+ });
970
+
971
+ // 🔥 使用更新后的列表计算折扣金额
972
+ var mainDiscountList = updatedMainDiscountList.filter(function (item) {
973
+ var _item$metadata;
974
+ return !(item !== null && item !== void 0 && (_item$metadata = item.metadata) !== null && _item$metadata !== void 0 && _item$metadata.custom_product_bundle_map_id);
975
+ });
976
+ if (mainDiscountList && mainDiscountList.length > 0) {
977
+ var allDiscountAmount = getDiscountListAmountTotal(mainDiscountList);
978
+ newTotalWithDiscount = new Decimal(mainProductData.price || 0).minus(allDiscountAmount).toNumber() || newTotalWithDiscount;
979
+ newOriginTotalWithDiscount = mainProductData.origin_total || newOriginTotalWithDiscount;
980
+ if (newBundleWithDiscount.length > 0) {
981
+ newBundleWithDiscount.forEach(function (item) {
982
+ var _item$discount_list3;
983
+ newTotalWithDiscount += Number(item.price) * Number(item.num);
984
+ var originalPrice = ((_item$discount_list3 = item.discount_list) === null || _item$discount_list3 === void 0 || (_item$discount_list3 = _item$discount_list3[0]) === null || _item$discount_list3 === void 0 || (_item$discount_list3 = _item$discount_list3.discount) === null || _item$discount_list3 === void 0 ? void 0 : _item$discount_list3.original_amount) || item.price;
985
+ newOriginTotalWithDiscount += Number(originalPrice) * Number(item.num);
986
+ });
987
+ }
988
+ }
989
+
990
+ // 添加第一个主商品:qty=1,包含拆分后的bundle
991
+ result.push(_this3.hooks.setProduct(mainProduct, _objectSpread(_objectSpread({}, mainProductData), {}, {
992
+ _id: "".concat(mainProductData._id.split('___')[0], "___split_discount"),
993
+ quantity: 1,
994
+ discount_list: updatedMainDiscountList,
995
+ bundle: newBundleWithDiscount,
996
+ total: newTotalWithDiscount,
997
+ origin_total: newOriginTotalWithDiscount
998
+ })));
999
+
1000
+ // 第二个:包含原始bundle (qty=原quantity-1)
1001
+ if (mainProductQuantity > 1) {
1002
+ var newBundleOriginal = [];
1003
+ (product.bundle || []).forEach(function (bundleItem, bundleIndex) {
1004
+ // 使用原始的bundle配置,不包含拆分
1005
+ newBundleOriginal.push(_objectSpread(_objectSpread({}, bundleItem), {}, {
1006
+ discount_list: []
1007
+ }));
1008
+ });
1009
+
1010
+ // 计算第二个主商品的总价
1011
+ var newTotalOriginal = Number(mainProductData.price || 0);
1012
+ var newOriginTotalOriginal = Number(mainProductData.original_price || mainProductData.price || 0);
1013
+ if (newBundleOriginal.length > 0) {
1014
+ newBundleOriginal.forEach(function (item) {
1015
+ newTotalOriginal += Number(item.price) * Number(item.num);
1016
+ newOriginTotalOriginal += Number(item.price) * Number(item.num);
1017
+ });
1018
+ }
1019
+
1020
+ // 🔥 更新主商品自己的 discount_list 中的 num(quantity=原quantity-1)
1021
+ var updatedMainDiscountListOriginal = mainProductData.discount_list.map(function (discount) {
1022
+ var _discount$metadata3;
1023
+ if (discount !== null && discount !== void 0 && (_discount$metadata3 = discount.metadata) !== null && _discount$metadata3 !== void 0 && _discount$metadata3.custom_product_bundle_map_id) {
1024
+ // bundle的discount_list保持不变
1025
+ return discount;
1026
+ }
1027
+ // 主商品自己的discount,更新num为 mainProductQuantity - 1
1028
+ return _objectSpread(_objectSpread({}, discount), {}, {
1029
+ num: mainProductQuantity - 1
1030
+ });
1031
+ });
1032
+
1033
+ // 🔥 使用更新后的列表计算折扣金额
1034
+ var mainDiscountListOriginal = updatedMainDiscountListOriginal.filter(function (item) {
1035
+ var _item$metadata2;
1036
+ return !(item !== null && item !== void 0 && (_item$metadata2 = item.metadata) !== null && _item$metadata2 !== void 0 && _item$metadata2.custom_product_bundle_map_id);
1037
+ });
1038
+ if (mainDiscountListOriginal && mainDiscountListOriginal.length > 0) {
1039
+ var _allDiscountAmount = getDiscountListAmount(mainDiscountListOriginal);
1040
+ newTotalOriginal = new Decimal(mainProductData.price || 0).minus(_allDiscountAmount).toNumber() || newTotalOriginal;
1041
+ newOriginTotalOriginal = mainProductData.origin_total || newOriginTotalOriginal;
1042
+ if (newBundleOriginal.length > 0) {
1043
+ newBundleOriginal.forEach(function (item) {
1044
+ newTotalOriginal += Number(item.price) * Number(item.num);
1045
+ newOriginTotalOriginal += Number(item.price) * Number(item.num);
1046
+ });
1047
+ }
1048
+ }
1049
+
1050
+ // 添加第二个主商品:qty=原quantity-1,包含原始bundle
1051
+ result.push(_this3.hooks.setProduct(mainProduct, _objectSpread(_objectSpread({}, mainProductData), {}, {
1052
+ _id: "".concat(mainProductData._id.split('___')[0], "___split_normal"),
1053
+ quantity: mainProductQuantity - 1,
1054
+ discount_list: updatedMainDiscountListOriginal,
1055
+ bundle: newBundleOriginal,
1056
+ total: newTotalOriginal,
1057
+ origin_total: newOriginTotalOriginal
1058
+ })));
1059
+ }
1060
+ } else {
1061
+ // 🔥 没有子商品被拆分,使用原有逻辑
1062
+ mainProductArr.forEach(function (mainProduct) {
1063
+ var mainProductData = _this3.hooks.getProduct(mainProduct);
1064
+
1065
+ // 重组bundle
1066
+ var newBundle = [];
1067
+ if (product.bundle && Array.isArray(product.bundle)) {
1068
+ product.bundle.forEach(function (bundleItem, bundleIndex) {
1069
+ var bundleItemId = "".concat(product._id, "_bundle_").concat(bundleIndex);
1070
+ var processedBundleItems = processedFlatItemsMap.get(bundleItemId);
1071
+ if (!processedBundleItems || processedBundleItems.length === 0) {
1072
+ // 未处理的bundle item,保持原样
1073
+ newBundle.push(bundleItem);
1074
+ } else {
1075
+ // 🔥 关键:拆分后的bundle item
1076
+ processedBundleItems.forEach(function (item) {
1077
+ // 🔥 更新 discount_list 中的 num,使其与拆分后的 item.num 一致
1078
+ var updatedDiscountList = (item.discount_list || []).map(function (discount) {
1079
+ return _objectSpread(_objectSpread({}, discount), {}, {
1080
+ num: item.num // 使用拆分后的 num
1081
+ });
1082
+ });
1083
+ newBundle.push(_objectSpread(_objectSpread({}, bundleItem), {}, {
1084
+ _id: item._id,
1085
+ product_id: bundleItem.product_id,
1086
+ price: item.price,
1087
+ num: item.num,
1088
+ discount_list: updatedDiscountList
1089
+ }));
1090
+ });
1091
+ }
1092
+ });
1093
+ }
1094
+
1095
+ // 🔥 重新计算主商品的总价(包含bundle)
1096
+ var newTotal = Number(mainProductData.price || 0);
1097
+ var newOriginTotal = Number(mainProductData.original_price || mainProductData.price || 0);
1098
+
1099
+ // 累加bundle的价格
1100
+ if (newBundle.length > 0) {
1101
+ newBundle.forEach(function (item) {
1102
+ newTotal += Number(item.price) * Number(item.num);
1103
+ });
1104
+
1105
+ // 计算原始总价(不考虑折扣)
1106
+ newBundle.forEach(function (item) {
1107
+ var _item$discount_list4;
1108
+ var originalPrice = ((_item$discount_list4 = item.discount_list) === null || _item$discount_list4 === void 0 || (_item$discount_list4 = _item$discount_list4[0]) === null || _item$discount_list4 === void 0 || (_item$discount_list4 = _item$discount_list4.discount) === null || _item$discount_list4 === void 0 ? void 0 : _item$discount_list4.original_amount) || item.price;
1109
+ newOriginTotal += Number(originalPrice) * Number(item.num);
1110
+ });
1111
+ }
1112
+ var mainDiscountList = mainProductData.discount_list.filter(function (item) {
1113
+ var _item$metadata3;
1114
+ return !(item !== null && item !== void 0 && (_item$metadata3 = item.metadata) !== null && _item$metadata3 !== void 0 && _item$metadata3.custom_product_bundle_map_id);
1115
+ });
1116
+
1117
+ // 如果主商品本身有折扣,需要重新计算
1118
+ if (mainDiscountList && mainDiscountList.length > 0) {
1119
+ var _allDiscountAmount2 = getDiscountListAmount(mainDiscountList);
1120
+ newTotal = new Decimal(mainProductData.price || 0).minus(_allDiscountAmount2).toNumber() || newTotal;
1121
+ newOriginTotal = mainProductData.origin_total || newOriginTotal;
1122
+
1123
+ // 累加bundle的价格
1124
+ if (newBundle.length > 0) {
1125
+ newBundle.forEach(function (item) {
1126
+ var _item$discount_list5;
1127
+ newTotal += Number(item.price) * Number(item.num);
1128
+ var originalPrice = ((_item$discount_list5 = item.discount_list) === null || _item$discount_list5 === void 0 || (_item$discount_list5 = _item$discount_list5[0]) === null || _item$discount_list5 === void 0 || (_item$discount_list5 = _item$discount_list5.discount) === null || _item$discount_list5 === void 0 ? void 0 : _item$discount_list5.original_amount) || item.price;
1129
+ newOriginTotal += Number(originalPrice) * Number(item.num);
1130
+ });
1131
+ }
1132
+ }
1133
+
1134
+ // 生成最终的主商品
1135
+ result.push(_this3.hooks.setProduct(mainProduct, _objectSpread(_objectSpread({}, mainProductData), {}, {
1136
+ bundle: newBundle,
1137
+ total: newTotal,
1138
+ origin_total: newOriginTotal
1139
+ })));
1140
+ });
1141
+ }
583
1142
  }
584
- };
585
- var arr = processedProductsMap.get(product._id);
586
- arr !== null && arr !== void 0 && arr.length ? processedProductList.push.apply(processedProductList, _toConsumableArray(arr)) : processedProductList.push(getDefaultProduct());
587
- });
1143
+ });
1144
+ return result;
1145
+ };
1146
+
1147
+ // 按原始顺序构建处理后的商品列表
1148
+ var processedProductList = reconstructProductsWithBundle(processedProductsMap, processedFlatItemsMap, productList);
588
1149
 
589
1150
  // 按原始顺序更新优惠券列表,标记已使用和可用的优惠券
590
1151
  var updatedDiscountList = addModeDiscount.map(function (discount) {
@@ -655,6 +1216,119 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
655
1216
  discountList: [].concat(editModeDiscount, _toConsumableArray(updatedDiscountList))
656
1217
  };
657
1218
  }
1219
+
1220
+ /**
1221
+ * 检查优惠是否符合 PackageSubItemUsageRules 配置
1222
+ * @param discount 优惠券
1223
+ * @param flatItem 扁平化后的商品项(可能是主商品或bundle子商品)
1224
+ * @returns 是否可用
1225
+ */
1226
+ }, {
1227
+ key: "checkPackageSubItemUsageRules",
1228
+ value: function checkPackageSubItemUsageRules(discount, flatItem) {
1229
+ var limitedData = discount.limited_relation_product_data;
1230
+ var usageRules = limitedData === null || limitedData === void 0 ? void 0 : limitedData.package_sub_item_usage_rules;
1231
+
1232
+ // 如果没有配置 package_sub_item_usage_rules,则默认可用
1233
+ if (!usageRules) {
1234
+ return true;
1235
+ }
1236
+ var ruleType = usageRules.type;
1237
+ var isMainProduct = flatItem.type === 'main'; // 单独购买
1238
+ var isBundleItem = flatItem.type === 'bundle'; // 套餐中购买
1239
+
1240
+ // universal_discount: 单独购买和套餐中(子商品为原价)均可使用
1241
+ if (ruleType === 'universal_discount') {
1242
+ if (isMainProduct) {
1243
+ return true; // 单独购买时可用
1244
+ }
1245
+ if (isBundleItem) {
1246
+ var _flatItem$bundleItem5, _flatItem$bundleItem6;
1247
+ // 套餐中购买时,判断是否为原价
1248
+ var priceType = (_flatItem$bundleItem5 = flatItem.bundleItem) === null || _flatItem$bundleItem5 === void 0 ? void 0 : _flatItem$bundleItem5.price_type;
1249
+ var priceTypeExt = (_flatItem$bundleItem6 = flatItem.bundleItem) === null || _flatItem$bundleItem6 === void 0 ? void 0 : _flatItem$bundleItem6.price_type_ext;
1250
+ // 原价包括:price_type: "markup" && price_type_ext: "product_price"
1251
+ return priceType === 'markup' && priceTypeExt === 'product_price';
1252
+ }
1253
+ return true;
1254
+ }
1255
+
1256
+ // package_exclusive: 仅在套餐中(子商品为原价)时可使用
1257
+ if (ruleType === 'package_exclusive') {
1258
+ if (isMainProduct) {
1259
+ return false; // 单独购买时不可用
1260
+ }
1261
+ if (isBundleItem) {
1262
+ var _flatItem$bundleItem7, _flatItem$bundleItem8;
1263
+ // 套餐中购买时,判断是否为原价
1264
+ var _priceType = (_flatItem$bundleItem7 = flatItem.bundleItem) === null || _flatItem$bundleItem7 === void 0 ? void 0 : _flatItem$bundleItem7.price_type;
1265
+ var _priceTypeExt = (_flatItem$bundleItem8 = flatItem.bundleItem) === null || _flatItem$bundleItem8 === void 0 ? void 0 : _flatItem$bundleItem8.price_type_ext;
1266
+ // 原价包括:price_type: "markup" && price_type_ext: "product_price"
1267
+ return _priceType === 'markup' && _priceTypeExt === 'product_price';
1268
+ }
1269
+ return false;
1270
+ }
1271
+
1272
+ // single_item_promo: 仅在单独购买时可使用
1273
+ if (ruleType === 'single_item_promo') {
1274
+ return isMainProduct; // 只有单独购买时可用
1275
+ }
1276
+
1277
+ // custom_usage_rules: 根据自定义规则判断
1278
+ if (ruleType === 'custom_usage_rules') {
1279
+ var customRules = usageRules.custom_usage_rules;
1280
+ if (!customRules) {
1281
+ return true; // 如果没有自定义规则,默认可用
1282
+ }
1283
+ var types = customRules.types,
1284
+ package_sub_item_rules = customRules.package_sub_item_rules;
1285
+
1286
+ // 判断商品类型是否在允许的类型中
1287
+ if (isMainProduct) {
1288
+ // 主商品对应 standalone_product
1289
+ if (!types.includes('standalone_product')) {
1290
+ return false;
1291
+ }
1292
+ return true; // 主商品不需要判断 package_sub_item_rules
1293
+ }
1294
+ if (isBundleItem) {
1295
+ var _flatItem$bundleItem9, _flatItem$bundleItem10;
1296
+ // bundle子商品对应 package_sub_item
1297
+ if (!types.includes('package_sub_item')) {
1298
+ return false;
1299
+ }
1300
+
1301
+ // 如果包含 package_sub_item,还需要判断 price_type
1302
+ var _priceType2 = (_flatItem$bundleItem9 = flatItem.bundleItem) === null || _flatItem$bundleItem9 === void 0 ? void 0 : _flatItem$bundleItem9.price_type;
1303
+ var _priceTypeExt2 = (_flatItem$bundleItem10 = flatItem.bundleItem) === null || _flatItem$bundleItem10 === void 0 ? void 0 : _flatItem$bundleItem10.price_type_ext;
1304
+
1305
+ // 检查 package_sub_item_rules
1306
+ if (package_sub_item_rules && package_sub_item_rules.length > 0) {
1307
+ // original_price 对应:
1308
+ // 1. price_type: "markup" && price_type_ext: "product_price"
1309
+ // markup_price 对应:
1310
+ // price_type: "markup" && price_type_ext: ""
1311
+
1312
+ var isOriginalPrice = _priceType2 === 'markup' && _priceTypeExt2 === 'product_price';
1313
+ var isMarkupPrice = _priceType2 === 'markup' && (_priceTypeExt2 === '' || !_priceTypeExt2);
1314
+ if (isOriginalPrice && package_sub_item_rules.includes('original_price')) {
1315
+ return true;
1316
+ }
1317
+ if (isMarkupPrice && package_sub_item_rules.includes('markup_price')) {
1318
+ return true;
1319
+ }
1320
+
1321
+ // 如果都不匹配,则不可用
1322
+ return false;
1323
+ }
1324
+ return true; // 如果没有 package_sub_item_rules 配置,默认可用
1325
+ }
1326
+ return true;
1327
+ }
1328
+
1329
+ // 默认可用
1330
+ return true;
1331
+ }
658
1332
  }, {
659
1333
  key: "destroy",
660
1334
  value: function () {