@pisell/pisellos 2.1.170 → 2.1.172

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 (231) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +1 -3
  3. package/dist/model/strategy/adapter/index.d.ts +0 -4
  4. package/dist/model/strategy/adapter/index.js +1 -5
  5. package/dist/model/strategy/adapter/promotion/evaluator.js +99 -26
  6. package/dist/model/strategy/adapter/promotion/index.js +0 -9
  7. package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
  8. package/dist/model/strategy/adapter/walletPass/evaluator.js +61 -8
  9. package/dist/model/strategy/adapter/walletPass/locales.js +12 -3
  10. package/dist/model/strategy/engine.d.ts +18 -5
  11. package/dist/model/strategy/engine.js +145 -45
  12. package/dist/model/strategy/type.d.ts +17 -0
  13. package/dist/model/strategy/type.js +4 -0
  14. package/dist/modules/Cart/types.d.ts +2 -0
  15. package/dist/modules/Cart/utils/cartProduct.js +56 -25
  16. package/dist/modules/Cart/utils/changePrice.js +9 -16
  17. package/dist/modules/Discount/index.d.ts +4 -13
  18. package/dist/modules/Discount/index.js +12 -124
  19. package/dist/modules/Discount/types.d.ts +18 -13
  20. package/dist/modules/Order/index.d.ts +1 -67
  21. package/dist/modules/Order/index.js +30 -918
  22. package/dist/modules/Order/types.d.ts +12 -176
  23. package/dist/modules/Order/types.js +0 -2
  24. package/dist/modules/Order/utils.d.ts +0 -118
  25. package/dist/modules/Order/utils.js +2 -586
  26. package/dist/modules/Payment/index.d.ts +2 -1
  27. package/dist/modules/Payment/index.js +10 -7
  28. package/dist/modules/Payment/utils.js +3 -0
  29. package/dist/modules/Payment/walletpass.d.ts +23 -0
  30. package/dist/modules/Payment/walletpass.js +191 -95
  31. package/dist/modules/Product/utils.js +2 -2
  32. package/dist/modules/ProductList/index.d.ts +2 -4
  33. package/dist/modules/ProductList/index.js +12 -24
  34. package/dist/modules/Rules/index.d.ts +9 -5
  35. package/dist/modules/Rules/index.js +669 -173
  36. package/dist/modules/Rules/types.d.ts +2 -0
  37. package/dist/modules/Schedule/getDateIsInSchedule.js +18 -16
  38. package/dist/modules/Schedule/utils.d.ts +1 -1
  39. package/dist/modules/Summary/types.d.ts +2 -0
  40. package/dist/modules/Summary/utils.d.ts +9 -3
  41. package/dist/modules/Summary/utils.js +57 -67
  42. package/dist/modules/index.d.ts +0 -4
  43. package/dist/modules/index.js +1 -5
  44. package/dist/plugins/window.d.ts +2 -0
  45. package/dist/solution/BookingByStep/index.d.ts +3 -2
  46. package/dist/solution/BookingByStep/index.js +43 -46
  47. package/dist/solution/BookingByStep/types.d.ts +1 -3
  48. package/dist/solution/BookingByStep/types.js +1 -5
  49. package/dist/solution/BookingByStep/utils/timeslots.d.ts +1 -3
  50. package/dist/solution/BookingByStep/utils/timeslots.js +12 -19
  51. package/dist/solution/Checkout/index.js +2 -0
  52. package/dist/solution/ShopDiscount/index.d.ts +2 -3
  53. package/dist/solution/ShopDiscount/index.js +60 -62
  54. package/dist/solution/ShopDiscount/types.d.ts +1 -1
  55. package/dist/solution/ShopDiscount/types.js +2 -1
  56. package/dist/solution/ShopDiscount/utils.js +26 -12
  57. package/dist/solution/index.d.ts +0 -2
  58. package/dist/solution/index.js +1 -3
  59. package/lib/index.d.ts +1 -1
  60. package/lib/index.js +3 -4
  61. package/lib/model/strategy/adapter/index.d.ts +0 -4
  62. package/lib/model/strategy/adapter/index.js +2 -13
  63. package/lib/model/strategy/adapter/promotion/evaluator.js +57 -8
  64. package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
  65. package/lib/model/strategy/adapter/walletPass/evaluator.js +34 -3
  66. package/lib/model/strategy/adapter/walletPass/locales.js +12 -3
  67. package/lib/model/strategy/engine.d.ts +18 -5
  68. package/lib/model/strategy/engine.js +85 -21
  69. package/lib/model/strategy/type.d.ts +17 -0
  70. package/lib/modules/Cart/types.d.ts +2 -0
  71. package/lib/modules/Cart/utils/cartProduct.js +39 -12
  72. package/lib/modules/Cart/utils/changePrice.js +9 -13
  73. package/lib/modules/Discount/index.d.ts +4 -13
  74. package/lib/modules/Discount/index.js +5 -76
  75. package/lib/modules/Discount/types.d.ts +18 -13
  76. package/lib/modules/Order/index.d.ts +1 -67
  77. package/lib/modules/Order/index.js +1 -525
  78. package/lib/modules/Order/types.d.ts +12 -176
  79. package/lib/modules/Order/utils.d.ts +0 -118
  80. package/lib/modules/Order/utils.js +2 -483
  81. package/lib/modules/Payment/index.d.ts +2 -1
  82. package/lib/modules/Payment/index.js +1 -0
  83. package/lib/modules/Payment/utils.js +3 -0
  84. package/lib/modules/Payment/walletpass.d.ts +23 -0
  85. package/lib/modules/Payment/walletpass.js +94 -17
  86. package/lib/modules/Product/utils.js +2 -2
  87. package/lib/modules/ProductList/index.d.ts +2 -4
  88. package/lib/modules/ProductList/index.js +39 -46
  89. package/lib/modules/Rules/index.d.ts +9 -5
  90. package/lib/modules/Rules/index.js +776 -292
  91. package/lib/modules/Rules/types.d.ts +2 -0
  92. package/lib/modules/Schedule/getDateIsInSchedule.js +11 -13
  93. package/lib/modules/Schedule/utils.d.ts +1 -1
  94. package/lib/modules/Summary/types.d.ts +2 -0
  95. package/lib/modules/Summary/utils.d.ts +9 -3
  96. package/lib/modules/Summary/utils.js +34 -45
  97. package/lib/modules/index.d.ts +0 -4
  98. package/lib/modules/index.js +1 -9
  99. package/lib/plugins/window.d.ts +2 -0
  100. package/lib/solution/BookingByStep/index.d.ts +3 -2
  101. package/lib/solution/BookingByStep/index.js +4 -6
  102. package/lib/solution/BookingByStep/types.d.ts +1 -3
  103. package/lib/solution/BookingByStep/types.js +0 -10
  104. package/lib/solution/BookingByStep/utils/timeslots.d.ts +1 -3
  105. package/lib/solution/BookingByStep/utils/timeslots.js +11 -19
  106. package/lib/solution/Checkout/index.js +2 -0
  107. package/lib/solution/ShopDiscount/index.d.ts +2 -3
  108. package/lib/solution/ShopDiscount/index.js +27 -22
  109. package/lib/solution/ShopDiscount/types.d.ts +1 -1
  110. package/lib/solution/ShopDiscount/utils.js +10 -6
  111. package/lib/solution/index.d.ts +0 -2
  112. package/lib/solution/index.js +1 -5
  113. package/package.json +2 -2
  114. package/dist/apis/picoding.d.ts +0 -0
  115. package/dist/apis/picoding.js +0 -1
  116. package/dist/model/strategy/adapter/dataVariant/adapter.d.ts +0 -50
  117. package/dist/model/strategy/adapter/dataVariant/adapter.js +0 -167
  118. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +0 -89
  119. package/dist/model/strategy/adapter/dataVariant/evaluator.js +0 -867
  120. package/dist/model/strategy/adapter/dataVariant/examples.d.ts +0 -39
  121. package/dist/model/strategy/adapter/dataVariant/examples.js +0 -277
  122. package/dist/model/strategy/adapter/dataVariant/index.d.ts +0 -4
  123. package/dist/model/strategy/adapter/dataVariant/index.js +0 -4
  124. package/dist/model/strategy/adapter/dataVariant/type.d.ts +0 -149
  125. package/dist/model/strategy/adapter/dataVariant/type.js +0 -54
  126. package/dist/modules/OpenData/index.d.ts +0 -24
  127. package/dist/modules/OpenData/index.js +0 -173
  128. package/dist/modules/OpenData/types.d.ts +0 -73
  129. package/dist/modules/OpenData/types.js +0 -1
  130. package/dist/modules/OpenData/utils.d.ts +0 -2
  131. package/dist/modules/OpenData/utils.js +0 -75
  132. package/dist/modules/Quotation/index.d.ts +0 -48
  133. package/dist/modules/Quotation/index.js +0 -248
  134. package/dist/modules/Quotation/types.d.ts +0 -42
  135. package/dist/modules/Quotation/types.js +0 -1
  136. package/dist/modules/SalesSummary/index.d.ts +0 -63
  137. package/dist/modules/SalesSummary/index.js +0 -174
  138. package/dist/modules/SalesSummary/types.d.ts +0 -60
  139. package/dist/modules/SalesSummary/types.js +0 -1
  140. package/dist/modules/SalesSummary/utils.d.ts +0 -30
  141. package/dist/modules/SalesSummary/utils.js +0 -480
  142. package/dist/modules/ScanOrderLogger/index.d.ts +0 -23
  143. package/dist/modules/ScanOrderLogger/index.js +0 -174
  144. package/dist/modules/ScanOrderLogger/providers/feishu.d.ts +0 -2
  145. package/dist/modules/ScanOrderLogger/providers/feishu.js +0 -221
  146. package/dist/modules/ScanOrderLogger/providers/grafana.d.ts +0 -2
  147. package/dist/modules/ScanOrderLogger/providers/grafana.js +0 -50
  148. package/dist/modules/ScanOrderLogger/types.d.ts +0 -53
  149. package/dist/modules/ScanOrderLogger/types.js +0 -1
  150. package/dist/solution/ScanOrder/index.d.ts +0 -158
  151. package/dist/solution/ScanOrder/index.js +0 -3474
  152. package/dist/solution/ScanOrder/types.d.ts +0 -306
  153. package/dist/solution/ScanOrder/types.js +0 -35
  154. package/dist/solution/ScanOrder/utils.d.ts +0 -172
  155. package/dist/solution/ScanOrder/utils.js +0 -796
  156. package/dist/solution/VenueBooking/index.d.ts +0 -252
  157. package/dist/solution/VenueBooking/index.js +0 -3769
  158. package/dist/solution/VenueBooking/sales-section-4-annotated.json +0 -343
  159. package/dist/solution/VenueBooking/types.d.ts +0 -156
  160. package/dist/solution/VenueBooking/types.js +0 -22
  161. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +0 -11
  162. package/dist/solution/VenueBooking/utils/dateSummary.js +0 -91
  163. package/dist/solution/VenueBooking/utils/resource.d.ts +0 -14
  164. package/dist/solution/VenueBooking/utils/resource.js +0 -131
  165. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +0 -32
  166. package/dist/solution/VenueBooking/utils/slotMerge.js +0 -233
  167. package/dist/solution/VenueBooking/utils/smartPricing.d.ts +0 -71
  168. package/dist/solution/VenueBooking/utils/smartPricing.js +0 -302
  169. package/dist/solution/VenueBooking/utils/timeSlot.d.ts +0 -34
  170. package/dist/solution/VenueBooking/utils/timeSlot.js +0 -458
  171. package/dist/solution/VenueBooking/utils.d.ts +0 -1
  172. package/dist/solution/VenueBooking/utils.js +0 -1
  173. package/lib/apis/picoding.d.ts +0 -0
  174. package/lib/apis/picoding.js +0 -0
  175. package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +0 -50
  176. package/lib/model/strategy/adapter/dataVariant/adapter.js +0 -149
  177. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +0 -89
  178. package/lib/model/strategy/adapter/dataVariant/evaluator.js +0 -666
  179. package/lib/model/strategy/adapter/dataVariant/examples.d.ts +0 -39
  180. package/lib/model/strategy/adapter/dataVariant/examples.js +0 -293
  181. package/lib/model/strategy/adapter/dataVariant/index.d.ts +0 -4
  182. package/lib/model/strategy/adapter/dataVariant/index.js +0 -38
  183. package/lib/model/strategy/adapter/dataVariant/type.d.ts +0 -149
  184. package/lib/model/strategy/adapter/dataVariant/type.js +0 -31
  185. package/lib/modules/OpenData/index.d.ts +0 -24
  186. package/lib/modules/OpenData/index.js +0 -119
  187. package/lib/modules/OpenData/types.d.ts +0 -73
  188. package/lib/modules/OpenData/types.js +0 -17
  189. package/lib/modules/OpenData/utils.d.ts +0 -2
  190. package/lib/modules/OpenData/utils.js +0 -111
  191. package/lib/modules/Quotation/index.d.ts +0 -48
  192. package/lib/modules/Quotation/index.js +0 -152
  193. package/lib/modules/Quotation/types.d.ts +0 -42
  194. package/lib/modules/Quotation/types.js +0 -17
  195. package/lib/modules/SalesSummary/index.d.ts +0 -63
  196. package/lib/modules/SalesSummary/index.js +0 -105
  197. package/lib/modules/SalesSummary/types.d.ts +0 -60
  198. package/lib/modules/SalesSummary/types.js +0 -17
  199. package/lib/modules/SalesSummary/utils.d.ts +0 -30
  200. package/lib/modules/SalesSummary/utils.js +0 -420
  201. package/lib/modules/ScanOrderLogger/index.d.ts +0 -23
  202. package/lib/modules/ScanOrderLogger/index.js +0 -147
  203. package/lib/modules/ScanOrderLogger/providers/feishu.d.ts +0 -2
  204. package/lib/modules/ScanOrderLogger/providers/feishu.js +0 -157
  205. package/lib/modules/ScanOrderLogger/providers/grafana.d.ts +0 -2
  206. package/lib/modules/ScanOrderLogger/providers/grafana.js +0 -52
  207. package/lib/modules/ScanOrderLogger/types.d.ts +0 -53
  208. package/lib/modules/ScanOrderLogger/types.js +0 -17
  209. package/lib/solution/ScanOrder/index.d.ts +0 -158
  210. package/lib/solution/ScanOrder/index.js +0 -2135
  211. package/lib/solution/ScanOrder/types.d.ts +0 -306
  212. package/lib/solution/ScanOrder/types.js +0 -36
  213. package/lib/solution/ScanOrder/utils.d.ts +0 -172
  214. package/lib/solution/ScanOrder/utils.js +0 -658
  215. package/lib/solution/VenueBooking/index.d.ts +0 -252
  216. package/lib/solution/VenueBooking/index.js +0 -2204
  217. package/lib/solution/VenueBooking/sales-section-4-annotated.json +0 -343
  218. package/lib/solution/VenueBooking/types.d.ts +0 -156
  219. package/lib/solution/VenueBooking/types.js +0 -45
  220. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +0 -11
  221. package/lib/solution/VenueBooking/utils/dateSummary.js +0 -105
  222. package/lib/solution/VenueBooking/utils/resource.d.ts +0 -14
  223. package/lib/solution/VenueBooking/utils/resource.js +0 -92
  224. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +0 -32
  225. package/lib/solution/VenueBooking/utils/slotMerge.js +0 -236
  226. package/lib/solution/VenueBooking/utils/smartPricing.d.ts +0 -71
  227. package/lib/solution/VenueBooking/utils/smartPricing.js +0 -225
  228. package/lib/solution/VenueBooking/utils/timeSlot.d.ts +0 -34
  229. package/lib/solution/VenueBooking/utils/timeSlot.js +0 -343
  230. package/lib/solution/VenueBooking/utils.d.ts +0 -1
  231. package/lib/solution/VenueBooking/utils.js +0 -69
@@ -1,4 +1,8 @@
1
+ var _excluded = ["_original_add_price"],
2
+ _excluded2 = ["_original_price", "_original_add_price"];
1
3
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
5
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
2
6
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
7
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
8
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
@@ -31,7 +35,6 @@ import { getProductOriginTotalPrice, getProductTotalPrice } from "../Cart/utils"
31
35
  import Decimal from 'decimal.js';
32
36
  import { isBoolean } from 'lodash-es';
33
37
  import dayjs from 'dayjs';
34
-
35
38
  // 临时变量
36
39
  var flatItem;
37
40
  export var RulesModule = /*#__PURE__*/function (_BaseModule) {
@@ -44,6 +47,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
44
47
  _defineProperty(_assertThisInitialized(_this), "defaultName", 'rules');
45
48
  _defineProperty(_assertThisInitialized(_this), "defaultVersion", '1.0.0');
46
49
  _defineProperty(_assertThisInitialized(_this), "store", void 0);
50
+ _defineProperty(_assertThisInitialized(_this), "window", void 0);
51
+ // WindowPlugin 实例
47
52
  _defineProperty(_assertThisInitialized(_this), "hooks", void 0);
48
53
  _this.hooks = {};
49
54
  return _this;
@@ -58,7 +63,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
58
63
  this.core = core;
59
64
  this.hooks = options === null || options === void 0 ? void 0 : options.hooks;
60
65
  this.store = options === null || options === void 0 ? void 0 : options.store;
61
- case 3:
66
+ this.window = core.getPlugin('window');
67
+ case 4:
62
68
  case "end":
63
69
  return _context.stop();
64
70
  }
@@ -113,6 +119,12 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
113
119
  // 最终直接匹配 holder 是否相同
114
120
  return (productHolderId || orderHolderId) === discount.holder.holder_id;
115
121
  }
122
+ }, {
123
+ key: "getWalletPassEvaluator",
124
+ value: function getWalletPassEvaluator() {
125
+ var _this$window$getWalle, _this$window;
126
+ return (_this$window$getWalle = (_this$window = this.window).getWalletPassEvaluator) === null || _this$window$getWalle === void 0 ? void 0 : _this$window$getWalle.call(_this$window);
127
+ }
116
128
 
117
129
  // 判断discountList 是否可以对当前productList生效
118
130
  }, {
@@ -122,6 +134,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
122
134
  var oldDiscountList = _ref.oldDiscountList,
123
135
  newDiscountList = _ref.newDiscountList,
124
136
  productList = _ref.productList,
137
+ orderTotalAmount = _ref.orderTotalAmount,
125
138
  holders = _ref.holders,
126
139
  isFormSubject = _ref.isFormSubject;
127
140
  // 首先检查是否有新的优惠券可应用
@@ -156,6 +169,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
156
169
  var result = this.calcDiscount({
157
170
  discountList: mergedDiscountList,
158
171
  productList: _toConsumableArray(productList),
172
+ orderTotalAmount: orderTotalAmount,
159
173
  holders: holders,
160
174
  isFormSubject: isFormSubject
161
175
  }, {
@@ -289,7 +303,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
289
303
  var discountList = _ref2.discountList,
290
304
  productList = _ref2.productList,
291
305
  holders = _ref2.holders,
292
- isFormSubject = _ref2.isFormSubject;
306
+ isFormSubject = _ref2.isFormSubject,
307
+ orderTotalAmount = _ref2.orderTotalAmount;
293
308
  var editModeDiscount = [];
294
309
  var addModeDiscount = [];
295
310
  discountList.forEach(function (discount) {
@@ -538,18 +553,62 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
538
553
  return priceB.minus(priceA).toNumber();
539
554
  });
540
555
 
541
- // 检查商品是否被排除(全品类)
542
- var isProductIncludedByLimitedData = function isProductIncludedByLimitedData(limitedData, productId) {
543
- var excludedIds = (limitedData === null || limitedData === void 0 ? void 0 : limitedData.exclude_product_ids) || [];
544
- var isExcluded = (limitedData === null || limitedData === void 0 ? void 0 : limitedData.filter) === 1 && excludedIds.some(function (id) {
545
- return String(id) === String(productId);
556
+ // 🔥 为每个折扣卡/商品券执行策略检查并附加config
557
+ var evaluator = this.getWalletPassEvaluator();
558
+ if (evaluator) {
559
+ addModeDiscount.forEach(function (discount) {
560
+ var discountType = discount.tag || discount.type;
561
+ // 只对 good_pass 和 discount_card 类型执行策略检查
562
+ if (['good_pass', 'discount_card', 'product_discount_card'].includes(discountType)) {
563
+ var _discount$limited_rel, _discount$limited_rel2;
564
+ // 转换 discount 为 Voucher 格式
565
+ var voucher = {
566
+ id: discount.id,
567
+ amount: Number(discount.par_value || 0),
568
+ balance: Number(discount.balance || 0),
569
+ type: discountType,
570
+ product_id: discount.product_id,
571
+ unified_available_status: 1,
572
+ available_product_type: (_discount$limited_rel = discount.limited_relation_product_data) === null || _discount$limited_rel === void 0 ? void 0 : _discount$limited_rel.type,
573
+ available_product_ids: (_discount$limited_rel2 = discount.limited_relation_product_data) === null || _discount$limited_rel2 === void 0 ? void 0 : _discount$limited_rel2.product_ids
574
+ };
575
+
576
+ // 转换 sortedFlattenedList 为 Product 格式
577
+ var productsForEvaluate = sortedFlattenedList.map(function (item) {
578
+ var _item$product;
579
+ return {
580
+ product_id: item.id,
581
+ price: item.price || 0,
582
+ quantity: item.quantity || item.num || 1,
583
+ selling_price: item.price || 0,
584
+ product_options: item.type === 'main' ? (_item$product = item.product) === null || _item$product === void 0 ? void 0 : _item$product.options : undefined
585
+ };
586
+ });
587
+
588
+ // 调用策略检查
589
+ var result = evaluator.checkVoucherAvailability({
590
+ orderTotalAmount: orderTotalAmount,
591
+ products: productsForEvaluate,
592
+ vouchers: [voucher]
593
+ });
594
+
595
+ // 将 config 附加到 discount 对象
596
+ if (result.isAvailable) {
597
+ discount.config = _objectSpread(_objectSpread({}, result.config), {}, {
598
+ isAvailable: true
599
+ });
600
+ } else {
601
+ discount.config = {
602
+ isAvailable: false
603
+ };
604
+ }
605
+ }
546
606
  });
547
- return !isExcluded;
548
- };
607
+ }
549
608
 
550
609
  /**
551
- // 对productList按价格降序排序(用于应用优惠券时优先选择高价商品) 价格相同时使用quantity 排序
552
- const sortedProductList = [...productList].sort((a, b) => {
610
+ // 对productList按价格降序排序(用于应用优惠券时优先选择高价商品) 价格相同时使用quantity 排序
611
+ const sortedProductList = [...productList].sort((a, b) => {
553
612
  const aProduct = this.hooks.getProduct(a);
554
613
  const bProduct = this.hooks.getProduct(b);
555
614
  const priceA = new Decimal((aProduct.price as string) || '0');
@@ -567,6 +626,22 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
567
626
  // 标记已使用的优惠券
568
627
  var usedDiscounts = new Map();
569
628
 
629
+ // 🔥 统计每个 product_id(商品券商品id)已使用的数量,用于 maxUsagePerOrder 限制
630
+ var usedProductIdCounts = new Map();
631
+
632
+ // 🔥 统计每张折扣卡的 applicableProductLimit 已使用次数(跨商品全局计数)
633
+ var usedDiscountCardLimitCounts = new Map();
634
+
635
+ // 🔥 预先将 editModeDiscount 中的折扣卡计入 applicableProductLimit 已使用次数
636
+ editModeDiscount.forEach(function (discount) {
637
+ var discountType = discount.tag || discount.type;
638
+ if (['discount_card', 'product_discount_card'].includes(discountType)) {
639
+ var _discount$metadata4;
640
+ var currentCount = usedDiscountCardLimitCounts.get(discount.id) || 0;
641
+ usedDiscountCardLimitCounts.set(discount.id, currentCount + (((_discount$metadata4 = discount.metadata) === null || _discount$metadata4 === void 0 ? void 0 : _discount$metadata4.num) || 1));
642
+ }
643
+ });
644
+
570
645
  // 记录每个优惠券适用的商品ID
571
646
  var discountApplicability = new Map();
572
647
 
@@ -782,6 +857,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
782
857
  var _flatItem$parentProdu5;
783
858
  // bundle子商品:构造虚拟商品对象
784
859
  product = {
860
+ startDate: flatItem === null || flatItem === void 0 || (_flatItem$parentProdu5 = flatItem.parentProduct) === null || _flatItem$parentProdu5 === void 0 ? void 0 : _flatItem$parentProdu5.startDate,
785
861
  _id: flatItem._id,
786
862
  id: flatItem.id,
787
863
  price: flatItem.price,
@@ -790,13 +866,12 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
790
866
  total: flatItem.total,
791
867
  origin_total: flatItem.origin_total,
792
868
  booking_id: flatItem.booking_id,
793
- discount_list: flatItem.discount_list || [],
794
- startDate: (_flatItem$parentProdu5 = flatItem.parentProduct) === null || _flatItem$parentProdu5 === void 0 ? void 0 : _flatItem$parentProdu5.startDate
869
+ discount_list: flatItem.discount_list || []
795
870
  };
796
871
  originProduct = flatItem.originProduct;
797
872
  }
798
873
  addModeDiscount.forEach(function (discount) {
799
- var _product6, _product7, _product8, _product9, _flatItem$bundleItem3, _flatItem$bundleItem4;
874
+ var _product6, _product7, _product8, _product9, _flatItem$bundleItem3, _flatItem$bundleItem4, _discount$config;
800
875
  var limitedData = discount === null || discount === void 0 ? void 0 : discount.limited_relation_product_data;
801
876
  // 拿到discount配置的holder信息 product信息 product.holder 加在 isLimitedProduct
802
877
  var _tempVar = (flatItem === null || flatItem === void 0 ? void 0 : flatItem.type) === 'bundle' ? flatItem === null || flatItem === void 0 ? void 0 : flatItem.parentProduct : flatItem === null || flatItem === void 0 ? void 0 : flatItem.product;
@@ -807,7 +882,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
807
882
  var timeLimit = true;
808
883
  timeLimit = !!filterDiscountListByBookingTime([discount], (((_product6 = product) === null || _product6 === void 0 ? void 0 : _product6.startDate) || dayjs()).format('YYYY-MM-DD HH:mm:ss')).length;
809
884
  // 是符合折扣的商品
810
- var isLimitedProduct = (limitedData.type === 'product_all' || limitedData.product_ids && limitedData.product_ids.includes(product.id)) && isHolderMatch;
885
+ var isLimitedProduct = (limitedData.type === 'product_all' && limitedData.filter !== 1 || limitedData.type === 'product_all' && limitedData.filter === 1 && !limitedData.exclude_product_ids.includes(product.id) || limitedData.product_ids && limitedData.product_ids.includes(product.id)) && isHolderMatch;
811
886
 
812
887
  // 编辑的商品 使用了优惠券不可用
813
888
  var isAvailableProduct = flatItem.type === 'main' ? !((_product7 = product) !== null && _product7 !== void 0 && _product7.booking_id && (_product8 = product) !== null && _product8 !== void 0 && (_product8 = _product8.discount_list) !== null && _product8 !== void 0 && _product8.length && (_product9 = product) !== null && _product9 !== void 0 && (_product9 = _product9.discount_list) !== null && _product9 !== void 0 && _product9.every(function (discount) {
@@ -820,8 +895,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
820
895
  var isBundleAvailable = _this3.checkPackageSubItemUsageRules(discount, flatItem);
821
896
 
822
897
  // 判断优惠券是否适用于该商品
823
- if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable) {
824
- var _discountApplicabilit, _discount$metadata4, _discount$metadata5;
898
+ if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable && (_discount$config = discount.config) !== null && _discount$config !== void 0 && _discount$config.isAvailable) {
899
+ var _discountApplicabilit, _discount$metadata5, _discount$metadata6;
825
900
  // 记录此优惠券适用的商品
826
901
  (_discountApplicabilit = discountApplicability.get(discount.id)) === null || _discountApplicabilit === void 0 || _discountApplicabilit.push(product.id);
827
902
 
@@ -837,14 +912,15 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
837
912
  type: discountType,
838
913
  tag: discountType,
839
914
  discount: {
840
- discount_card_type: discount === null || discount === void 0 || (_discount$metadata4 = discount.metadata) === null || _discount$metadata4 === void 0 ? void 0 : _discount$metadata4.discount_card_type,
915
+ discount_card_type: discount === null || discount === void 0 || (_discount$metadata5 = discount.metadata) === null || _discount$metadata5 === void 0 ? void 0 : _discount$metadata5.discount_card_type,
841
916
  fixed_amount: product.price,
842
- discount_calculation_mode: discount === null || discount === void 0 || (_discount$metadata5 = discount.metadata) === null || _discount$metadata5 === void 0 ? void 0 : _discount$metadata5.discount_calculation_mode,
917
+ discount_calculation_mode: discount === null || discount === void 0 || (_discount$metadata6 = discount.metadata) === null || _discount$metadata6 === void 0 ? void 0 : _discount$metadata6.discount_calculation_mode,
843
918
  resource_id: discount.id,
844
919
  title: discount.format_title,
845
920
  original_amount: product.price || product.origin_total,
846
921
  pre_value: discount.par_value,
847
- product_id: originProduct.id
922
+ product_id: originProduct.id,
923
+ discount_product_id: discount.product_id
848
924
  },
849
925
  metadata: {
850
926
  num: num,
@@ -860,19 +936,75 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
860
936
  // 🔥 用于存储扁平化商品处理结果的Map
861
937
  var processedFlatItemsMap = new Map();
862
938
 
939
+ // 🔥 Option 折扣辅助函数
940
+ var applyDiscountToOptions = function applyDiscountToOptions(options, discount) {
941
+ if (!(options !== null && options !== void 0 && options.length)) return {
942
+ discountedOptions: options,
943
+ optionDiscountAmount: 0
944
+ };
945
+ var optionDiscountAmount = 0;
946
+ var discountedOptions = options.map(function (option) {
947
+ var _ref6, _ref7, _option$_original_pri, _ref8, _option$num, _rest$price, _option$_original_pri2;
948
+ // 折前单价:优先 price,缺失再 add_price;已写回折后价时用 _original_price(或旧字段 _original_add_price)
949
+ var rawUnit = (_ref6 = (_ref7 = (_option$_original_pri = option._original_price) !== null && _option$_original_pri !== void 0 ? _option$_original_pri : option._original_add_price) !== null && _ref7 !== void 0 ? _ref7 : option.price) !== null && _ref6 !== void 0 ? _ref6 : option.add_price;
950
+ var baseUnitNum = Number(rawUnit !== null && rawUnit !== void 0 ? rawUnit : 0);
951
+ if (baseUnitNum <= 0) return option;
952
+ var discountedPrice = getDiscountAmount(discount, baseUnitNum, baseUnitNum);
953
+ var optQty = Number((_ref8 = (_option$num = option.num) !== null && _option$num !== void 0 ? _option$num : option.quantity) !== null && _ref8 !== void 0 ? _ref8 : 1);
954
+ optionDiscountAmount = new Decimal(optionDiscountAmount).plus(new Decimal(baseUnitNum).minus(discountedPrice).mul(optQty)).toNumber();
955
+ var _original_add_price = option._original_add_price,
956
+ rest = _objectWithoutProperties(option, _excluded);
957
+ var tmpl = (_rest$price = rest.price) !== null && _rest$price !== void 0 ? _rest$price : rest.add_price;
958
+ var nextPrice = typeof tmpl === 'string' ? String(discountedPrice) : discountedPrice;
959
+ return _objectSpread(_objectSpread({}, rest), {}, {
960
+ _original_price: (_option$_original_pri2 = option._original_price) !== null && _option$_original_pri2 !== void 0 ? _option$_original_pri2 : _original_add_price !== undefined ? _original_add_price : rawUnit,
961
+ price: nextPrice
962
+ });
963
+ });
964
+ return {
965
+ discountedOptions: discountedOptions,
966
+ optionDiscountAmount: optionDiscountAmount
967
+ };
968
+ };
969
+ var restoreOptionPrices = function restoreOptionPrices(options) {
970
+ if (!(options !== null && options !== void 0 && options.length)) return options;
971
+ return options.map(function (option) {
972
+ var orig = option._original_price !== undefined ? option._original_price : option._original_add_price;
973
+ if (orig !== undefined) {
974
+ var _original_price = option._original_price,
975
+ _original_add_price = option._original_add_price,
976
+ rest = _objectWithoutProperties(option, _excluded2);
977
+ return _objectSpread(_objectSpread({}, rest), {}, {
978
+ price: orig
979
+ });
980
+ }
981
+ return option;
982
+ });
983
+ };
984
+ var getOptionTotal = function getOptionTotal(options) {
985
+ if (!(options !== null && options !== void 0 && options.length)) return 0;
986
+ return options.reduce(function (sum, opt) {
987
+ var _ref9, _opt$price, _ref10, _opt$num;
988
+ var unit = Number((_ref9 = (_opt$price = opt.price) !== null && _opt$price !== void 0 ? _opt$price : opt.add_price) !== null && _ref9 !== void 0 ? _ref9 : 0);
989
+ var n = Number((_ref10 = (_opt$num = opt.num) !== null && _opt$num !== void 0 ? _opt$num : opt.quantity) !== null && _ref10 !== void 0 ? _ref10 : 1);
990
+ return new Decimal(sum).plus(new Decimal(unit).mul(n)).toNumber();
991
+ }, 0);
992
+ };
993
+
863
994
  // 然后再处理应用哪些优惠券,此时只考虑filteredDiscountList中的优惠券
864
995
  // 🔥 使用扁平化后的列表进行处理
865
996
  sortedFlattenedList.forEach(function (flatItem, index) {
866
- var _product10, _product$discount_lis2, _product11;
997
+ var _product10, _product$discount_lis2, _product11, _selectedDiscount$con;
867
998
  // 获取商品数据
868
999
  var product, originProduct;
869
1000
  if (flatItem.type === 'main') {
870
1001
  product = flatItem.product;
871
1002
  originProduct = flatItem.originProduct;
872
1003
  } else {
873
- var _flatItem$bundleItem5, _flatItem$bundleItem6, _flatItem$bundleItem7, _flatItem$parentProdu6;
1004
+ var _flatItem$parentProdu6, _flatItem$bundleItem5, _flatItem$bundleItem6, _flatItem$bundleItem7;
874
1005
  // bundle子商品
875
1006
  product = {
1007
+ startDate: flatItem === null || flatItem === void 0 || (_flatItem$parentProdu6 = flatItem.parentProduct) === null || _flatItem$parentProdu6 === void 0 ? void 0 : _flatItem$parentProdu6.startDate,
876
1008
  _id: flatItem._id,
877
1009
  id: flatItem.id,
878
1010
  price: flatItem.price,
@@ -882,8 +1014,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
882
1014
  original_price: flatItem === null || flatItem === void 0 || (_flatItem$bundleItem5 = flatItem.bundleItem) === null || _flatItem$bundleItem5 === void 0 ? void 0 : _flatItem$bundleItem5.original_price,
883
1015
  origin_total: flatItem === null || flatItem === void 0 || (_flatItem$bundleItem6 = flatItem.bundleItem) === null || _flatItem$bundleItem6 === void 0 ? void 0 : _flatItem$bundleItem6.original_price,
884
1016
  booking_id: flatItem.booking_id,
885
- discount_list: (flatItem === null || flatItem === void 0 || (_flatItem$bundleItem7 = flatItem.bundleItem) === null || _flatItem$bundleItem7 === void 0 ? void 0 : _flatItem$bundleItem7.discount_list) || [],
886
- startDate: (_flatItem$parentProdu6 = flatItem.parentProduct) === null || _flatItem$parentProdu6 === void 0 ? void 0 : _flatItem$parentProdu6.startDate
1017
+ discount_list: (flatItem === null || flatItem === void 0 || (_flatItem$bundleItem7 = flatItem.bundleItem) === null || _flatItem$bundleItem7 === void 0 ? void 0 : _flatItem$bundleItem7.discount_list) || []
887
1018
  };
888
1019
  originProduct = flatItem.originProduct;
889
1020
  }
@@ -905,18 +1036,53 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
905
1036
  // 找到适用于此商品的所有优惠券,仅考虑isSelected不为false的优惠券
906
1037
  var applicableDiscounts = sortedDiscountList.filter(function (discount) {
907
1038
  var _product$discount_lis3, _product$discount_lis4;
1039
+ // 🔥 检查策略可用性(针对 good_pass 和折扣卡)
1040
+ var discountType = discount.tag || discount.type;
1041
+ if (['good_pass', 'discount_card', 'product_discount_card'].includes(discountType)) {
1042
+ var _discount$config2;
1043
+ // 如果策略检查后没有config,说明不可用
1044
+ if (discount.config === undefined || !(discount !== null && discount !== void 0 && (_discount$config2 = discount.config) !== null && _discount$config2 !== void 0 && _discount$config2.isAvailable)) {
1045
+ return false;
1046
+ }
1047
+ }
1048
+
908
1049
  // 如果商品价格为 0,其实不需要使用任何优惠券,直接 return true
909
1050
  // 商品券时主商品价格为0不可用
910
1051
  if ((Number(product.price) <= 0 || !product.price) && !((_product$discount_lis3 = product.discount_list) !== null && _product$discount_lis3 !== void 0 && _product$discount_lis3.length) && (discount.tag || discount.type) === 'good_pass') return false;
911
1052
 
912
1053
  // 折扣卡商品价格为0时不可用
913
- if ((Number(product.price) <= 0 || !product.price) && !((_product$discount_lis4 = product.discount_list) !== null && _product$discount_lis4 !== void 0 && _product$discount_lis4.find(function (n) {
1054
+ if ((Number(product.total) <= 0 || !product.total) && !((_product$discount_lis4 = product.discount_list) !== null && _product$discount_lis4 !== void 0 && _product$discount_lis4.find(function (n) {
914
1055
  var _n$discount;
915
1056
  return ((_n$discount = n.discount) === null || _n$discount === void 0 ? void 0 : _n$discount.resource_id) === discount.id;
916
1057
  })) && (discount.tag || discount.type) !== 'good_pass') return false;
917
1058
  // 如果优惠券已被使用,则跳过
918
1059
  var targetUsedDiscounts = usedDiscounts.get(discount.id);
919
1060
  if (targetUsedDiscounts && (discount.tag || discount.type) === 'good_pass') return false;
1061
+
1062
+ // 🔥 检查 maxUsagePerOrder 限制:同一 product_id 的商品券使用数量不能超过配置值
1063
+ if ((discount.tag || discount.type) === 'good_pass') {
1064
+ var _discount$config3;
1065
+ var maxUsagePerOrder = (_discount$config3 = discount.config) === null || _discount$config3 === void 0 ? void 0 : _discount$config3.maxUsagePerOrder;
1066
+ if (maxUsagePerOrder && maxUsagePerOrder > 0) {
1067
+ var currentUsedCount = usedProductIdCounts.get(discount.product_id) || 0;
1068
+ if (currentUsedCount >= maxUsagePerOrder) {
1069
+ return false;
1070
+ }
1071
+ }
1072
+ }
1073
+
1074
+ // 🔥 检查折扣卡的 applicableProductLimit 限制:折扣卡可使用的最大次数(跨商品全局)
1075
+ var discountTypeForLimit = discount.tag || discount.type;
1076
+ if (['discount_card', 'product_discount_card'].includes(discountTypeForLimit)) {
1077
+ var _discount$config4;
1078
+ var applicableProductLimitConfig = ((_discount$config4 = discount.config) === null || _discount$config4 === void 0 ? void 0 : _discount$config4.applicableProductLimit) || 0;
1079
+ if (applicableProductLimitConfig > 0) {
1080
+ var currentUsedLimitCount = usedDiscountCardLimitCounts.get(discount.id) || 0;
1081
+ if (currentUsedLimitCount >= applicableProductLimitConfig) {
1082
+ return false;
1083
+ }
1084
+ }
1085
+ }
920
1086
  var limitedData = discount.limited_relation_product_data;
921
1087
 
922
1088
  // 拿到discount配置的holder信息 product信息 product.holder 不可用return false
@@ -935,10 +1101,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
935
1101
 
936
1102
  // 判断优惠券是否适用于该商品
937
1103
  if (limitedData.type === 'product_all') {
938
- if (!isProductIncludedByLimitedData(limitedData, product.id)) {
1104
+ if (limitedData.filter === 1 && limitedData.exclude_product_ids.includes(product.id)) {
939
1105
  return false;
940
1106
  }
941
-
942
1107
  // 检查 package_sub_item_usage_rules
943
1108
  if (!_this3.checkPackageSubItemUsageRules(discount, flatItem)) {
944
1109
  return false;
@@ -968,19 +1133,22 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
968
1133
  var _product$discount_lis5, _product12, _product12$every;
969
1134
  // 主商品:判断自身是否手动折扣
970
1135
  isManualDiscount = typeof product.isManualDiscount === 'boolean' ? product.isManualDiscount : product.total != product.origin_total && (product.bundle || []).every(function (item) {
971
- var _ref6;
972
- return !((_ref6 = item.discount_list || []) !== null && _ref6 !== void 0 && _ref6.length);
1136
+ var _ref11;
1137
+ return !((_ref11 = item.discount_list || []) !== null && _ref11 !== void 0 && _ref11.length);
973
1138
  }) && (!((_product$discount_lis5 = product.discount_list) !== null && _product$discount_lis5 !== void 0 && _product$discount_lis5.length) || ((_product12 = product) === null || _product12 === void 0 || (_product12 = _product12.discount_list) === null || _product12 === void 0 || (_product12$every = _product12.every) === null || _product12$every === void 0 ? void 0 : _product12$every.call(_product12, function (item) {
974
1139
  return item.type === 'product';
975
1140
  })));
1141
+ if (product.inPromotion) {
1142
+ isManualDiscount = false;
1143
+ }
976
1144
  } else {
977
1145
  // bundle子商品:判断父主商品是否手动折扣
978
1146
  var parentProduct = flatItem.parentProduct;
979
1147
  if (parentProduct) {
980
1148
  var _parentProduct$discou, _parentProduct$discou2, _parentProduct$discou3;
981
1149
  isManualDiscount = typeof parentProduct.isManualDiscount === 'boolean' ? parentProduct.isManualDiscount : parentProduct.total != parentProduct.origin_total && (parentProduct.bundle || []).every(function (item) {
982
- var _ref7;
983
- return !((_ref7 = item.discount_list || []) !== null && _ref7 !== void 0 && _ref7.length);
1150
+ var _ref12;
1151
+ return !((_ref12 = item.discount_list || []) !== null && _ref12 !== void 0 && _ref12.length);
984
1152
  }) && (!((_parentProduct$discou = parentProduct.discount_list) !== null && _parentProduct$discou !== void 0 && _parentProduct$discou.length) || (parentProduct === null || parentProduct === void 0 || (_parentProduct$discou2 = parentProduct.discount_list) === null || _parentProduct$discou2 === void 0 || (_parentProduct$discou3 = _parentProduct$discou2.every) === null || _parentProduct$discou3 === void 0 ? void 0 : _parentProduct$discou3.call(_parentProduct$discou2, function (item) {
985
1153
  return item.type === 'product';
986
1154
  })));
@@ -1047,7 +1215,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1047
1215
  // 如果没有适用的优惠券,或者手动折扣,则不适用优惠券
1048
1216
  if (applicableDiscounts.length === 0 || isManualDiscount || isBoolean(product.vouchersApplicable) && !product.vouchersApplicable) {
1049
1217
  if (flatItem.type === 'main') {
1050
- // 主商品:保持原有逻辑
1218
+ // 主商品:保持原有逻辑,还原 option 价格
1219
+ var restoredOptions = restoreOptionPrices(product.options);
1051
1220
  if (product.isClient) {
1052
1221
  processedProductsMap.set(product._id, [_this3.hooks.setProduct(originProduct, _objectSpread(_objectSpread({}, isManualDiscount ? {} : {
1053
1222
  origin_total: getProductOriginTotalPrice({
@@ -1055,7 +1224,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1055
1224
  original_price: product.original_price
1056
1225
  },
1057
1226
  bundle: product.bundle,
1058
- options: product.options
1227
+ options: restoredOptions
1059
1228
  }),
1060
1229
  variant: originProduct._productInit.variant,
1061
1230
  original_price: originProduct._productInit.original_price,
@@ -1064,16 +1233,16 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1064
1233
  price: product.price
1065
1234
  },
1066
1235
  bundle: product.bundle,
1067
- options: product.options
1236
+ options: restoredOptions
1068
1237
  }),
1069
1238
  price: product.price,
1070
- options: product.options
1239
+ options: restoredOptions
1071
1240
  }), {}, {
1072
1241
  discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion')
1073
1242
  }))]);
1074
1243
  } else {
1075
- var _ref8, _product$_promotion$f, _product13, _product$origin_total, _product$price2;
1076
- var total = product.inPromotion ? (_ref8 = (_product$_promotion$f = (_product13 = product) === null || _product13 === void 0 || (_product13 = _product13._promotion) === null || _product13 === void 0 ? void 0 : _product13.finalPrice) !== null && _product$_promotion$f !== void 0 ? _product$_promotion$f : product.origin_total) !== null && _ref8 !== void 0 ? _ref8 : product.total : (_product$origin_total = product.origin_total) !== null && _product$origin_total !== void 0 ? _product$origin_total : product.total;
1244
+ var _ref13, _product$_promotion$f, _product13, _product$origin_total, _product$price2;
1245
+ var total = product.inPromotion ? (_ref13 = (_product$_promotion$f = (_product13 = product) === null || _product13 === void 0 || (_product13 = _product13._promotion) === null || _product13 === void 0 ? void 0 : _product13.finalPrice) !== null && _product$_promotion$f !== void 0 ? _product$_promotion$f : product.origin_total) !== null && _ref13 !== void 0 ? _ref13 : product.total : (_product$origin_total = product.origin_total) !== null && _product$origin_total !== void 0 ? _product$origin_total : product.total;
1077
1246
  var main_product_selling_price = (_product$price2 = product.price) !== null && _product$price2 !== void 0 ? _product$price2 : product.main_product_selling_price;
1078
1247
  if ((product.discount_list || []).some(function (item) {
1079
1248
  return item.type === 'promotion';
@@ -1086,11 +1255,10 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1086
1255
  price: product.price
1087
1256
  } : {
1088
1257
  _id: product._id.split('___')[0] + '___' + index,
1089
- origin_total: product.origin_total,
1090
1258
  total: total,
1091
- original_price: product.original_price,
1092
1259
  price: product.price,
1093
- main_product_selling_price: main_product_selling_price
1260
+ main_product_selling_price: main_product_selling_price,
1261
+ options: restoredOptions
1094
1262
  }), {}, {
1095
1263
  discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion')
1096
1264
  }))]);
@@ -1110,36 +1278,81 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1110
1278
  return;
1111
1279
  }
1112
1280
 
1113
- // 是否需要拆分(商品券需要拆分)
1114
- var isNeedSplit = (selectedDiscount.tag || selectedDiscount.type) === 'good_pass';
1281
+ // 是否需要拆分(商品券需要拆分,折扣卡在 applicableProductLimit > 0 时也需要拆分)
1282
+ var discountType = selectedDiscount.tag || selectedDiscount.type;
1283
+ var isGoodPass = discountType === 'good_pass';
1284
+ var isDiscountCard = ['discount_card', 'product_discount_card'].includes(discountType);
1285
+ var applicableProductLimit = ((_selectedDiscount$con = selectedDiscount.config) === null || _selectedDiscount$con === void 0 ? void 0 : _selectedDiscount$con.applicableProductLimit) || 0;
1286
+
1287
+ // 商品券始终需要拆分,折扣卡在 applicableProductLimit > 0 时需要拆分
1288
+ var isNeedSplit = isGoodPass || isDiscountCard && applicableProductLimit > 0;
1115
1289
 
1116
1290
  // 需要拆分出来的数量
1117
1291
  var totalQuantity = product.quantity || product.num || 1;
1118
1292
  var availableGoodPassCount = applicableDiscounts.filter(function (item) {
1119
1293
  return (item.tag || item.type) === 'good_pass';
1120
1294
  }).length;
1121
- var splitCount = isNeedSplit ? Math.min(totalQuantity, availableGoodPassCount) : 1;
1295
+
1296
+ // 🔥 计算最大使用次数限制
1297
+ var maxUsageLimit;
1298
+ if (isGoodPass) {
1299
+ // 商品券:使用 maxUsagePerOrder 限制
1300
+ maxUsageLimit = availableGoodPassCount;
1301
+ if (selectedDiscount.config && selectedDiscount.config.maxUsagePerOrder) {
1302
+ maxUsageLimit = Math.min(availableGoodPassCount, selectedDiscount.config.maxUsagePerOrder);
1303
+ }
1304
+ } else if (isDiscountCard && applicableProductLimit > 0) {
1305
+ // 折扣卡:使用 applicableProductLimit 限制(一个商品使用一次折扣卡算1次)
1306
+ // 需要减去已使用次数(跨商品全局计数)
1307
+ var usedLimitCount = usedDiscountCardLimitCounts.get(selectedDiscount.id) || 0;
1308
+ maxUsageLimit = Math.max(0, applicableProductLimit - usedLimitCount);
1309
+ } else {
1310
+ // 其他情况不拆分
1311
+ maxUsageLimit = 1;
1312
+ }
1313
+ var splitCount = isNeedSplit ? Math.min(product.quantity || product.num || 1, maxUsageLimit) : 1;
1122
1314
  var arr = [];
1123
1315
 
1124
1316
  // 🔥 主商品和bundle子商品分别处理
1125
1317
  if (flatItem.type === 'main') {
1126
1318
  // 主商品:保持原有逻辑
1127
1319
  if (splitCount < totalQuantity && isNeedSplit) {
1320
+ var _product$origin_total2;
1321
+ var _total = (_product$origin_total2 = product.origin_total) !== null && _product$origin_total2 !== void 0 ? _product$origin_total2 : product.total;
1322
+ if ((product.discount_list || []).some(function (item) {
1323
+ return item.type === 'promotion';
1324
+ })) {
1325
+ var _product$total2;
1326
+ _total = (_product$total2 = product.total) !== null && _product$total2 !== void 0 ? _product$total2 : product.origin_total;
1327
+ }
1128
1328
  arr.push(_this3.hooks.setProduct(originProduct, {
1129
1329
  discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion'),
1130
1330
  quantity: totalQuantity - splitCount,
1131
- _id: product._id.split('___')[0]
1331
+ _id: product._id.split('___')[0],
1332
+ total: _total
1132
1333
  }));
1133
1334
  }
1134
1335
  for (var i = 0; i < splitCount; i++) {
1135
- var _originProduct, _selectedDiscount$met, _selectedDiscount$met2;
1136
- // 如果用过折扣卡,也就不存在拆分的情况了,这里直接使用上面计算出来的折扣卡
1137
- var _selectedDiscount = selectedDiscountCard || applicableDiscounts[i];
1336
+ var _originProduct, _selectedDiscount$con2, _product$options, _product$options2, _selectedDiscount$met, _selectedDiscount$met2;
1337
+ // 商品券:每个拆分商品使用不同的商品券(从 applicableDiscounts 按索引取)
1338
+ // 折扣卡:所有拆分商品使用同一张折扣卡(selectedDiscountCard applicableDiscounts[0]
1339
+ var currentSelectedDiscount = isGoodPass ? selectedDiscountCard || applicableDiscounts[i] : selectedDiscountCard || applicableDiscounts[0];
1138
1340
  // 标记优惠券为已使用
1139
- usedDiscounts.set(_selectedDiscount.id, true);
1341
+ usedDiscounts.set(currentSelectedDiscount.id, true);
1342
+ // 🔥 更新 product_id 使用计数
1343
+ if ((currentSelectedDiscount.tag || currentSelectedDiscount.type) === 'good_pass') {
1344
+ var currentCount = usedProductIdCounts.get(currentSelectedDiscount.product_id) || 0;
1345
+ usedProductIdCounts.set(currentSelectedDiscount.product_id, currentCount + 1);
1346
+ }
1347
+ // 🔥 更新折扣卡 applicableProductLimit 使用计数(跨商品全局)
1348
+ var currentDiscountTypeForCount = currentSelectedDiscount.tag || currentSelectedDiscount.type;
1349
+ if (['discount_card', 'product_discount_card'].includes(currentDiscountTypeForCount)) {
1350
+ var currentLimitCount = usedDiscountCardLimitCounts.get(currentSelectedDiscount.id) || 0;
1351
+ usedDiscountCardLimitCounts.set(currentSelectedDiscount.id, currentLimitCount + 1);
1352
+ }
1140
1353
 
1141
1354
  // 记录实际应用了优惠券的商品信息
1142
- var appliedProducts = appliedDiscountProducts.get(_selectedDiscount.id) || [];
1355
+ var appliedProducts = appliedDiscountProducts.get(currentSelectedDiscount.id) || [];
1143
1356
 
1144
1357
  // 优先从 origin_total拿,可能会拿不到(比如用户端预约在没有配置 original_price 的情况下)
1145
1358
  var productOriginTotal = product.origin_total || product.total || 0;
@@ -1154,210 +1367,492 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1154
1367
 
1155
1368
  // 计算使用折扣卡/商品券以后,单个商品的总 total
1156
1369
  // 🔥 检查是否是 order_level 固定金额折扣卡
1157
- var isOrderLevel = isOrderLevelFixedAmountDiscount(_selectedDiscount);
1158
- var orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(_selectedDiscount.id) : null;
1370
+ var isOrderLevel = isOrderLevelFixedAmountDiscount(selectedDiscount);
1371
+ var orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount.id) : null;
1159
1372
  var productAllocation = orderLevelAllocation === null || orderLevelAllocation === void 0 ? void 0 : orderLevelAllocation.get(flatItem._id);
1160
- var targetProductTotal = void 0;
1373
+ var isDeductOptionPrice = !!((_selectedDiscount$con2 = selectedDiscount.config) !== null && _selectedDiscount$con2 !== void 0 && _selectedDiscount$con2.deductOptionPrice);
1374
+
1375
+ // 主商品折后价(不含 option);勿与 option 合计混在同一变量,否则 main_product_selling_price 错误
1376
+ var mainProductSellingPrice = void 0;
1161
1377
  var amount = void 0;
1162
1378
  var productDiscountDifference = void 0;
1379
+ var discountedOptions = product.options;
1380
+ var optionDiscountAmount = 0;
1163
1381
  if (isOrderLevel && productAllocation) {
1164
1382
  // order_level:使用预计算的分摊金额
1165
1383
  amount = productAllocation.discountAmount;
1166
1384
  productDiscountDifference = productAllocation.difference;
1167
- targetProductTotal = Math.max(new Decimal(product.price).minus(amount).toNumber(), 0);
1385
+ mainProductSellingPrice = Math.max(new Decimal(product.price).minus(amount).toNumber(), 0);
1168
1386
  } else {
1169
1387
  // item_level 或其他类型:使用原有逻辑
1170
- targetProductTotal = getDiscountAmount(_selectedDiscount, product.price, product.price);
1171
- amount = new Decimal(product.price).minus(new Decimal(targetProductTotal)).toNumber();
1388
+ mainProductSellingPrice = getDiscountAmount(currentSelectedDiscount, product.price, product.price);
1389
+ amount = new Decimal(product.price).minus(new Decimal(mainProductSellingPrice)).toNumber();
1172
1390
  }
1173
- var discountType = _selectedDiscount.tag || _selectedDiscount.type;
1174
- var isGoodPass = discountType === 'good_pass';
1391
+ if (isDeductOptionPrice && (_product$options = product.options) !== null && _product$options !== void 0 && _product$options.length) {
1392
+ var optionResult = applyDiscountToOptions(product.options, currentSelectedDiscount);
1393
+ discountedOptions = optionResult.discountedOptions;
1394
+ optionDiscountAmount = optionResult.optionDiscountAmount;
1395
+ }
1396
+
1397
+ // total = 主商品折后 + option 行合计;开启 option 抵扣时必须用 discountedOptions,不能用未折扣的 product.options 再算一遍
1398
+ var optionsForLineTotal = isDeductOptionPrice && (_product$options2 = product.options) !== null && _product$options2 !== void 0 && _product$options2.length ? discountedOptions : product.options;
1399
+ var optionsLineTotal = getOptionTotal(optionsForLineTotal || []);
1400
+ var _total2 = new Decimal(mainProductSellingPrice).plus(optionsLineTotal).toNumber();
1401
+
1402
+ // discount_list.amount / fixed_amount:行级总优惠 = 主商品优惠 + option 优惠(与 total 变化一致)
1403
+ var mainProductDiscountAmount = amount;
1404
+ var lineDiscountAmount = new Decimal(mainProductDiscountAmount).plus(optionDiscountAmount).toNumber();
1405
+ var currentDiscountType = currentSelectedDiscount.tag === 'product_discount_card' ? 'discount_card' : currentSelectedDiscount.tag;
1406
+ var _discountType = selectedDiscount.tag || selectedDiscount.type;
1407
+ var currentIsGoodPass = currentDiscountType === 'good_pass';
1175
1408
  var discountDetail = {
1176
- amount: amount,
1177
- type: _selectedDiscount.tag === 'product_discount_card' ? 'discount_card' : discountType,
1409
+ amount: lineDiscountAmount,
1410
+ type: selectedDiscount.tag === 'product_discount_card' ? 'discount_card' : _discountType,
1178
1411
  discount: {
1179
- discount_card_type: _selectedDiscount === null || _selectedDiscount === void 0 || (_selectedDiscount$met = _selectedDiscount.metadata) === null || _selectedDiscount$met === void 0 ? void 0 : _selectedDiscount$met.discount_card_type,
1180
- fixed_amount: amount,
1181
- discount_calculation_mode: _selectedDiscount === null || _selectedDiscount === void 0 || (_selectedDiscount$met2 = _selectedDiscount.metadata) === null || _selectedDiscount$met2 === void 0 ? void 0 : _selectedDiscount$met2.discount_calculation_mode,
1182
- resource_id: _selectedDiscount.id,
1183
- title: _selectedDiscount.format_title,
1412
+ discount_card_type: selectedDiscount === null || selectedDiscount === void 0 || (_selectedDiscount$met = selectedDiscount.metadata) === null || _selectedDiscount$met === void 0 ? void 0 : _selectedDiscount$met.discount_card_type,
1413
+ fixed_amount: lineDiscountAmount,
1414
+ discount_calculation_mode: selectedDiscount === null || selectedDiscount === void 0 || (_selectedDiscount$met2 = selectedDiscount.metadata) === null || _selectedDiscount$met2 === void 0 ? void 0 : _selectedDiscount$met2.discount_calculation_mode,
1415
+ resource_id: selectedDiscount.id,
1416
+ title: selectedDiscount.format_title,
1184
1417
  original_amount: product.price,
1185
1418
  product_id: originProduct.id,
1186
- percent: _selectedDiscount.par_value
1419
+ percent: currentSelectedDiscount.par_value,
1420
+ discount_product_id: currentSelectedDiscount.product_id
1187
1421
  },
1188
- // 前端使用的num数量,为了计算优惠金额
1189
- _num: isGoodPass ? 1 : product.num,
1190
- metadata: _objectSpread({
1422
+ // 前端使用的num数量,为了计算优惠金额(拆分时为1)
1423
+ _num: isNeedSplit ? 1 : product.num,
1424
+ config: currentSelectedDiscount === null || currentSelectedDiscount === void 0 ? void 0 : currentSelectedDiscount.config,
1425
+ metadata: _objectSpread(_objectSpread({
1191
1426
  num: 1,
1192
- discount_rule_uncheck_flag: _selectedDiscount === null || _selectedDiscount === void 0 ? void 0 : _selectedDiscount.discount_rule_uncheck_flag
1427
+ discount_rule_uncheck_flag: selectedDiscount === null || selectedDiscount === void 0 ? void 0 : selectedDiscount.discount_rule_uncheck_flag
1193
1428
  }, productDiscountDifference !== undefined && {
1194
1429
  product_discount_difference: productDiscountDifference
1430
+ }), {}, {
1431
+ /** 仅主商品上的优惠金额(不含 option) */
1432
+ mainProductDiscountAmount: mainProductDiscountAmount,
1433
+ optionDiscountAmount: optionDiscountAmount
1195
1434
  })
1196
1435
  };
1197
1436
  appliedProducts.push(discountDetail);
1198
- appliedDiscountProducts.set(_selectedDiscount.id, appliedProducts);
1199
- var _total = targetProductTotal;
1200
- if (product.options) {
1201
- _total = product.options.reduce(function (accumulator, currentValue) {
1202
- var currentPrice = new Decimal(currentValue.price || 0);
1203
- var currentNum = new Decimal(currentValue.num || 0);
1204
- return accumulator.add(currentPrice.mul(currentNum));
1205
- }, new Decimal(_total)).toNumber();
1206
- }
1437
+ appliedDiscountProducts.set(currentSelectedDiscount.id, appliedProducts);
1207
1438
 
1208
1439
  // 记录应用了优惠券的商品
1209
1440
  // 后续更新价格改为 getProductTotalPrice getProductOriginTotalPrice逻辑
1210
1441
  if (product.isClient) {
1211
1442
  arr.push(_this3.hooks.setProduct(originProduct, {
1212
1443
  discount_list: [discountDetail],
1213
- price: _selectedDiscount.tag === 'good_pass' ? 0 : product.price,
1444
+ // good_pass:主商品价以折后价为准;勿用 product.price - amount(amount option 优惠时会算错)
1445
+ price: currentIsGoodPass ? mainProductSellingPrice : product.price,
1214
1446
  quantity: isNeedSplit ? 1 : product.quantity,
1215
1447
  origin_total: getProductOriginTotalPrice({
1216
1448
  product: {
1217
1449
  original_price: product.original_price
1218
1450
  },
1219
1451
  bundle: product.bundle,
1220
- options: product.options
1452
+ options: restoreOptionPrices(product.options)
1221
1453
  }),
1222
1454
  variant: originProduct._productInit.variant,
1223
1455
  original_price: new Decimal(product.price || 0).toNumber(),
1224
- total: _total
1456
+ total: _total2,
1457
+ options: discountedOptions
1225
1458
  }));
1226
1459
  } else {
1227
1460
  arr.push(_this3.hooks.setProduct(originProduct, {
1228
1461
  discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion').concat([discountDetail]),
1229
- _id: product._id.split('___')[0] + "___" + _selectedDiscount.id + index,
1230
- price: _selectedDiscount.tag === 'good_pass' ? 0 : product.price,
1462
+ _id: product._id.split('___')[0] + '___' + currentSelectedDiscount.id + '_' + i + '_' + index,
1463
+ price: currentIsGoodPass ? 0 : product.price,
1231
1464
  quantity: isNeedSplit ? 1 : product.quantity,
1232
- total: _total,
1465
+ total: _total2,
1233
1466
  origin_total: productOriginTotal,
1234
- main_product_selling_price: targetProductTotal
1467
+ main_product_selling_price: mainProductSellingPrice,
1468
+ options: discountedOptions
1235
1469
  }));
1236
1470
  }
1237
1471
  }
1238
1472
  processedProductsMap.set(product._id, arr);
1239
1473
  } else {
1240
- // 🔥 bundle子商品:支持拆分
1474
+ // 🔥 bundle子商品:支持拆分(商品券和折扣卡在 applicableProductLimit > 0 时都需要拆分)
1241
1475
  var processedItems = [];
1242
1476
  if (isNeedSplit) {
1243
- // 商品券:需要拆分数量
1477
+ // 需要拆分数量(商品券或折扣卡有 applicableProductLimit 限制)
1244
1478
  var discountNum = splitCount;
1245
1479
  var normalNum = totalQuantity - discountNum;
1246
1480
 
1247
- // 生成有折扣的商品(每张商品券对应 num: 1)
1481
+ // 生成有折扣的商品(每个拆分商品 num: 1)
1248
1482
  for (var _i = 0; _i < discountNum; _i++) {
1249
- var _selectedDiscount2$me;
1250
- var _selectedDiscount2 = applicableDiscounts[_i];
1251
- usedDiscounts.set(_selectedDiscount2.id, true);
1483
+ var _currentBundleDiscoun, _currentBundleDiscoun2;
1484
+ // 商品券:每个拆分商品使用不同的商品券
1485
+ // 折扣卡:所有拆分商品使用同一张折扣卡
1486
+ var currentBundleDiscount = isGoodPass ? selectedDiscountCard || applicableDiscounts[_i] : selectedDiscountCard || applicableDiscounts[0];
1487
+ usedDiscounts.set(currentBundleDiscount.id, true);
1488
+ // 🔥 更新 product_id 使用计数
1489
+ if ((currentBundleDiscount.tag || currentBundleDiscount.type) === 'good_pass') {
1490
+ var _currentCount = usedProductIdCounts.get(currentBundleDiscount.product_id) || 0;
1491
+ usedProductIdCounts.set(currentBundleDiscount.product_id, _currentCount + 1);
1492
+ }
1493
+ // 🔥 更新折扣卡 applicableProductLimit 使用计数(跨商品全局)
1494
+ var bundleDiscountTypeForCount = currentBundleDiscount.tag || currentBundleDiscount.type;
1495
+ if (['discount_card', 'product_discount_card'].includes(bundleDiscountTypeForCount)) {
1496
+ var currentBundleLimitCount = usedDiscountCardLimitCounts.get(currentBundleDiscount.id) || 0;
1497
+ usedDiscountCardLimitCounts.set(currentBundleDiscount.id, currentBundleLimitCount + 1);
1498
+ }
1252
1499
 
1253
1500
  // 🔥 生成唯一的 _id
1254
1501
  var uniqueId = "".concat(flatItem._id, "_split_").concat(_i);
1502
+
1503
+ // 计算折扣后的价格(使用 getDiscountAmount,内部已处理 maxDeductionAmount)
1504
+ var discountedPrice = getDiscountAmount(currentBundleDiscount, product.origin_total, product.origin_total);
1505
+ var bundleDiscountAmount = new Decimal(product.origin_total || 0).minus(discountedPrice).toNumber();
1506
+
1507
+ // 确定折扣类型
1508
+ var bundleDiscountType = currentBundleDiscount.tag === 'product_discount_card' ? 'discount_card' : currentBundleDiscount.tag;
1255
1509
  var _discountDetail = {
1256
- amount: product.origin_total,
1257
- type: 'good_pass',
1510
+ amount: bundleDiscountAmount,
1511
+ type: bundleDiscountType,
1258
1512
  discount: {
1259
- fixed_amount: product.origin_total,
1260
- discount_calculation_mode: _selectedDiscount2 === null || _selectedDiscount2 === void 0 || (_selectedDiscount2$me = _selectedDiscount2.metadata) === null || _selectedDiscount2$me === void 0 ? void 0 : _selectedDiscount2$me.discount_calculation_mode,
1261
- resource_id: _selectedDiscount2.id,
1262
- title: _selectedDiscount2.format_title,
1513
+ discount_card_type: currentBundleDiscount === null || currentBundleDiscount === void 0 || (_currentBundleDiscoun = currentBundleDiscount.metadata) === null || _currentBundleDiscoun === void 0 ? void 0 : _currentBundleDiscoun.discount_card_type,
1514
+ discount_calculation_mode: currentBundleDiscount === null || currentBundleDiscount === void 0 || (_currentBundleDiscoun2 = currentBundleDiscount.metadata) === null || _currentBundleDiscoun2 === void 0 ? void 0 : _currentBundleDiscoun2.discount_calculation_mode,
1515
+ fixed_amount: bundleDiscountAmount,
1516
+ resource_id: currentBundleDiscount.id,
1517
+ title: currentBundleDiscount.format_title,
1263
1518
  original_amount: product.origin_total,
1264
- product_id: product.id
1519
+ product_id: product.id,
1520
+ percent: currentBundleDiscount.par_value,
1521
+ discount_product_id: currentBundleDiscount.product_id
1265
1522
  },
1266
1523
  metadata: {
1267
1524
  // 🔥 使用拆分后的唯一 _id
1268
1525
  custom_product_bundle_map_id: uniqueId,
1269
- discount_rule_uncheck_flag: _selectedDiscount2 === null || _selectedDiscount2 === void 0 ? void 0 : _selectedDiscount2.discount_rule_uncheck_flag,
1526
+ discount_rule_uncheck_flag: selectedDiscount === null || selectedDiscount === void 0 ? void 0 : selectedDiscount.discount_rule_uncheck_flag,
1270
1527
  num: 1
1271
1528
  },
1272
- _num: 1
1529
+ _num: 1,
1530
+ config: currentBundleDiscount === null || currentBundleDiscount === void 0 ? void 0 : currentBundleDiscount.config
1273
1531
  };
1274
1532
 
1275
1533
  // 记录实际应用的折扣
1276
- var _appliedProducts = appliedDiscountProducts.get(_selectedDiscount2.id) || [];
1534
+ var _appliedProducts = appliedDiscountProducts.get(currentBundleDiscount.id) || [];
1277
1535
  _appliedProducts.push(_discountDetail);
1278
- appliedDiscountProducts.set(_selectedDiscount2.id, _appliedProducts);
1536
+ appliedDiscountProducts.set(currentBundleDiscount.id, _appliedProducts);
1279
1537
  processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1280
1538
  // 🔥 使用唯一的 _id
1281
1539
  _id: uniqueId,
1282
1540
  num: 1,
1283
1541
  quantity: 1,
1284
- price: 0,
1285
- // 商品券价格为0
1286
- total: 0,
1542
+ price: discountedPrice,
1543
+ // 折扣后的价格
1544
+ total: discountedPrice,
1287
1545
  discount_list: _this3.filterDiscountListByType(flatItem.discount_list, 'promotion').concat([_discountDetail]),
1288
1546
  processed: true,
1289
- _discountId: _selectedDiscount2.id
1547
+ _discountId: currentBundleDiscount.id
1290
1548
  }));
1291
1549
  }
1292
1550
 
1293
- // 生成无折扣的商品(剩余数量)
1294
- if (normalNum > 0) {
1295
- processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1296
- // 🔥 为剩余商品生成唯一的 _id
1297
- _id: "".concat(flatItem._id, "_split_rest"),
1298
- num: normalNum,
1299
- quantity: normalNum,
1300
- discount_list: _this3.filterDiscountListByType(flatItem.discount_list, 'promotion'),
1301
- processed: true
1302
- }));
1551
+ // 🔥 对拆分后的剩余商品继续匹配其他可用折扣(而不是等到下次执行才应用)
1552
+ var remainingNum = normalNum;
1553
+ var continueSplitIndex = discountNum;
1554
+ while (remainingNum > 0) {
1555
+ var _nextSelectedDiscount;
1556
+ // 重新查找适用于剩余商品的可用折扣(已使用的会被自动过滤掉)
1557
+ var nextApplicableDiscounts = sortedDiscountList.filter(function (nextDiscount) {
1558
+ var _product$discount_lis10;
1559
+ var nextDiscountType = nextDiscount.tag || nextDiscount.type;
1560
+ // 检查策略可用性
1561
+ if (['good_pass', 'discount_card', 'product_discount_card'].includes(nextDiscountType)) {
1562
+ var _nextDiscount$config;
1563
+ if (nextDiscount.config === undefined || !(nextDiscount !== null && nextDiscount !== void 0 && (_nextDiscount$config = nextDiscount.config) !== null && _nextDiscount$config !== void 0 && _nextDiscount$config.isAvailable)) {
1564
+ return false;
1565
+ }
1566
+ }
1567
+ // 折扣卡时总价为0时不可用
1568
+ if ((Number(product.total) <= 0 || !product.total) && !((_product$discount_lis10 = product.discount_list) !== null && _product$discount_lis10 !== void 0 && _product$discount_lis10.find(function (n) {
1569
+ var _n$discount2;
1570
+ return ((_n$discount2 = n.discount) === null || _n$discount2 === void 0 ? void 0 : _n$discount2.resource_id) === nextDiscount.id;
1571
+ })) && nextDiscountType !== 'good_pass') return false;
1572
+
1573
+ // 商品券已被使用则跳过
1574
+ if (usedDiscounts.get(nextDiscount.id) && nextDiscountType === 'good_pass') return false;
1575
+
1576
+ // 检查 maxUsagePerOrder 限制
1577
+ if (nextDiscountType === 'good_pass') {
1578
+ var _nextDiscount$config2;
1579
+ var maxUsagePerOrder = (_nextDiscount$config2 = nextDiscount.config) === null || _nextDiscount$config2 === void 0 ? void 0 : _nextDiscount$config2.maxUsagePerOrder;
1580
+ if (maxUsagePerOrder && maxUsagePerOrder > 0) {
1581
+ var currentUsedCount = usedProductIdCounts.get(nextDiscount.product_id) || 0;
1582
+ if (currentUsedCount >= maxUsagePerOrder) {
1583
+ return false;
1584
+ }
1585
+ }
1586
+ }
1587
+
1588
+ // 检查折扣卡的 applicableProductLimit 限制
1589
+ if (['discount_card', 'product_discount_card'].includes(nextDiscountType)) {
1590
+ var _nextDiscount$config3;
1591
+ var limitConfig = ((_nextDiscount$config3 = nextDiscount.config) === null || _nextDiscount$config3 === void 0 ? void 0 : _nextDiscount$config3.applicableProductLimit) || 0;
1592
+ if (limitConfig > 0) {
1593
+ var currentUsedLimitCount = usedDiscountCardLimitCounts.get(nextDiscount.id) || 0;
1594
+ if (currentUsedLimitCount >= limitConfig) {
1595
+ return false;
1596
+ }
1597
+ }
1598
+ }
1599
+ var limitedData = nextDiscount.limited_relation_product_data;
1600
+ if (limitedData.type === 'product_all') {
1601
+ if (limitedData.filter === 1 && limitedData.exclude_product_ids.includes(product.id)) {
1602
+ return false;
1603
+ }
1604
+ if (!_this3.checkPackageSubItemUsageRules(nextDiscount, flatItem)) {
1605
+ return false;
1606
+ }
1607
+ return true;
1608
+ } else if (limitedData.product_ids && limitedData.product_ids.includes(product.id)) {
1609
+ if (!_this3.checkPackageSubItemUsageRules(nextDiscount, flatItem)) {
1610
+ return false;
1611
+ }
1612
+ return true;
1613
+ }
1614
+ return false;
1615
+ });
1616
+
1617
+ // 没有更多可用折扣,剩余商品无折扣存储
1618
+ if (nextApplicableDiscounts.length === 0) {
1619
+ processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1620
+ _id: "".concat(flatItem._id, "_split_rest"),
1621
+ num: remainingNum,
1622
+ quantity: remainingNum,
1623
+ discount_list: [],
1624
+ processed: true
1625
+ }));
1626
+ break;
1627
+ }
1628
+
1629
+ // 选择最优折扣
1630
+ var nextSelectedDiscountCard = nextApplicableDiscounts.find(function (n) {
1631
+ return n.isScan && n.isSelected && (n.tag || n.type) !== 'good_pass';
1632
+ });
1633
+ var nextSelectedDiscount = nextSelectedDiscountCard || nextApplicableDiscounts[0];
1634
+
1635
+ // 判断新折扣是否需要拆分
1636
+ var nextDiscType = nextSelectedDiscount.tag || nextSelectedDiscount.type;
1637
+ var nextIsGoodPass = nextDiscType === 'good_pass';
1638
+ var nextIsDiscountCard = ['discount_card', 'product_discount_card'].includes(nextDiscType);
1639
+ var nextApplicableProductLimit = ((_nextSelectedDiscount = nextSelectedDiscount.config) === null || _nextSelectedDiscount === void 0 ? void 0 : _nextSelectedDiscount.applicableProductLimit) || 0;
1640
+ var nextIsNeedSplit = nextIsGoodPass || nextIsDiscountCard && nextApplicableProductLimit > 0;
1641
+ if (!nextIsNeedSplit) {
1642
+ var _nextBundleDiscount$m, _flatItem$parentProdu9;
1643
+ // 🔥 不需要拆分:直接应用折扣到所有剩余商品
1644
+ var nextBundleDiscount = nextSelectedDiscountCard || nextApplicableDiscounts[0];
1645
+ usedDiscounts.set(nextBundleDiscount.id, true);
1646
+ if ((nextBundleDiscount.tag || nextBundleDiscount.type) === 'good_pass') {
1647
+ var curCount = usedProductIdCounts.get(nextBundleDiscount.product_id) || 0;
1648
+ usedProductIdCounts.set(nextBundleDiscount.product_id, curCount + 1);
1649
+ }
1650
+ var nextNoSplitType = nextBundleDiscount.tag || nextBundleDiscount.type;
1651
+ if (['discount_card', 'product_discount_card'].includes(nextNoSplitType)) {
1652
+ var _curCount = usedDiscountCardLimitCounts.get(nextBundleDiscount.id) || 0;
1653
+ usedDiscountCardLimitCounts.set(nextBundleDiscount.id, _curCount + remainingNum);
1654
+ }
1655
+ var nextOriginTotal = product.original_price || product.price || 0;
1656
+ var nextTargetTotal = getDiscountAmount(nextBundleDiscount, nextOriginTotal, nextOriginTotal);
1657
+ var nextDiscountAmount = new Decimal(nextOriginTotal).minus(nextTargetTotal).toNumber();
1658
+ var nextUniqueId = "".concat(flatItem._id, "_split_").concat(continueSplitIndex);
1659
+ var nextBundleDiscType = nextBundleDiscount.tag === 'product_discount_card' ? 'discount_card' : nextBundleDiscount.tag;
1660
+ var nextDiscountDetail = {
1661
+ amount: nextDiscountAmount * remainingNum,
1662
+ type: nextBundleDiscType,
1663
+ discount: {
1664
+ discount_card_type: nextBundleDiscount === null || nextBundleDiscount === void 0 || (_nextBundleDiscount$m = nextBundleDiscount.metadata) === null || _nextBundleDiscount$m === void 0 ? void 0 : _nextBundleDiscount$m.discount_card_type,
1665
+ fixed_amount: nextDiscountAmount,
1666
+ resource_id: nextBundleDiscount.id,
1667
+ title: nextBundleDiscount.format_title,
1668
+ original_amount: product.original_price,
1669
+ product_id: product.id,
1670
+ percent: nextBundleDiscount.par_value,
1671
+ discount_product_id: nextBundleDiscount.product_id
1672
+ },
1673
+ metadata: {
1674
+ custom_product_bundle_map_id: nextUniqueId,
1675
+ num: remainingNum
1676
+ },
1677
+ config: nextBundleDiscount === null || nextBundleDiscount === void 0 ? void 0 : nextBundleDiscount.config,
1678
+ _num: remainingNum * ((flatItem === null || flatItem === void 0 || (_flatItem$parentProdu9 = flatItem.parentProduct) === null || _flatItem$parentProdu9 === void 0 ? void 0 : _flatItem$parentProdu9.num) || 1)
1679
+ };
1680
+ var nextAppliedProducts = appliedDiscountProducts.get(nextBundleDiscount.id) || [];
1681
+ nextAppliedProducts.push(nextDiscountDetail);
1682
+ appliedDiscountProducts.set(nextBundleDiscount.id, nextAppliedProducts);
1683
+ processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1684
+ _id: nextUniqueId,
1685
+ num: remainingNum,
1686
+ quantity: remainingNum,
1687
+ total: nextTargetTotal,
1688
+ price: new Decimal(nextOriginTotal || 0).minus(nextDiscountDetail.discount.fixed_amount).toNumber(),
1689
+ discount_list: [nextDiscountDetail],
1690
+ processed: true
1691
+ }));
1692
+ remainingNum = 0;
1693
+ break;
1694
+ }
1695
+
1696
+ // 🔥 需要拆分:计算最大使用次数
1697
+ var nextMaxUsageLimit = void 0;
1698
+ if (nextIsGoodPass) {
1699
+ var _nextSelectedDiscount2;
1700
+ var nextGoodPassCount = nextApplicableDiscounts.filter(function (item) {
1701
+ return (item.tag || item.type) === 'good_pass';
1702
+ }).length;
1703
+ nextMaxUsageLimit = nextGoodPassCount;
1704
+ if ((_nextSelectedDiscount2 = nextSelectedDiscount.config) !== null && _nextSelectedDiscount2 !== void 0 && _nextSelectedDiscount2.maxUsagePerOrder) {
1705
+ var usedCount = usedProductIdCounts.get(nextSelectedDiscount.product_id) || 0;
1706
+ nextMaxUsageLimit = Math.min(nextGoodPassCount, Math.max(0, nextSelectedDiscount.config.maxUsagePerOrder - usedCount));
1707
+ }
1708
+ } else if (nextIsDiscountCard && nextApplicableProductLimit > 0) {
1709
+ var _usedLimitCount = usedDiscountCardLimitCounts.get(nextSelectedDiscount.id) || 0;
1710
+ nextMaxUsageLimit = Math.max(0, nextApplicableProductLimit - _usedLimitCount);
1711
+ } else {
1712
+ nextMaxUsageLimit = 1;
1713
+ }
1714
+ var nextSplitCount = Math.min(remainingNum, nextMaxUsageLimit);
1715
+ if (nextSplitCount === 0) {
1716
+ // 已达使用上限,剩余商品无折扣存储
1717
+ processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1718
+ _id: "".concat(flatItem._id, "_split_rest"),
1719
+ num: remainingNum,
1720
+ quantity: remainingNum,
1721
+ discount_list: _this3.filterDiscountListByType(flatItem.discount_list, 'promotion'),
1722
+ processed: true
1723
+ }));
1724
+ break;
1725
+ }
1726
+
1727
+ // 生成有折扣的商品
1728
+ for (var j = 0; j < nextSplitCount; j++) {
1729
+ var _nextBundleDiscount$m2;
1730
+ var _nextBundleDiscount = nextIsGoodPass ? nextSelectedDiscountCard || nextApplicableDiscounts[j] : nextSelectedDiscountCard || nextApplicableDiscounts[0];
1731
+ usedDiscounts.set(_nextBundleDiscount.id, true);
1732
+ if ((_nextBundleDiscount.tag || _nextBundleDiscount.type) === 'good_pass') {
1733
+ var _curCount2 = usedProductIdCounts.get(_nextBundleDiscount.product_id) || 0;
1734
+ usedProductIdCounts.set(_nextBundleDiscount.product_id, _curCount2 + 1);
1735
+ }
1736
+ var nextBundleDiscTypeForCount = _nextBundleDiscount.tag || _nextBundleDiscount.type;
1737
+ if (['discount_card', 'product_discount_card'].includes(nextBundleDiscTypeForCount)) {
1738
+ var curLimitCount = usedDiscountCardLimitCounts.get(_nextBundleDiscount.id) || 0;
1739
+ usedDiscountCardLimitCounts.set(_nextBundleDiscount.id, curLimitCount + 1);
1740
+ }
1741
+ var _nextUniqueId = "".concat(flatItem._id, "_split_").concat(continueSplitIndex);
1742
+ var nextDiscountedPrice = getDiscountAmount(_nextBundleDiscount, product.origin_total, product.origin_total);
1743
+ var nextBundleDiscAmount = new Decimal(product.origin_total || 0).minus(nextDiscountedPrice).toNumber();
1744
+ var nextBundleDiscTypeStr = _nextBundleDiscount.tag === 'product_discount_card' ? 'discount_card' : _nextBundleDiscount.tag;
1745
+ var _nextDiscountDetail = {
1746
+ amount: nextBundleDiscAmount,
1747
+ type: nextBundleDiscTypeStr,
1748
+ discount: {
1749
+ discount_card_type: _nextBundleDiscount === null || _nextBundleDiscount === void 0 || (_nextBundleDiscount$m2 = _nextBundleDiscount.metadata) === null || _nextBundleDiscount$m2 === void 0 ? void 0 : _nextBundleDiscount$m2.discount_card_type,
1750
+ fixed_amount: nextBundleDiscAmount,
1751
+ resource_id: _nextBundleDiscount.id,
1752
+ title: _nextBundleDiscount.format_title,
1753
+ original_amount: product.origin_total,
1754
+ product_id: product.id,
1755
+ percent: _nextBundleDiscount.par_value,
1756
+ discount_product_id: _nextBundleDiscount.product_id
1757
+ },
1758
+ metadata: {
1759
+ custom_product_bundle_map_id: _nextUniqueId,
1760
+ num: 1
1761
+ },
1762
+ _num: 1,
1763
+ config: _nextBundleDiscount === null || _nextBundleDiscount === void 0 ? void 0 : _nextBundleDiscount.config
1764
+ };
1765
+ var _nextAppliedProducts = appliedDiscountProducts.get(_nextBundleDiscount.id) || [];
1766
+ _nextAppliedProducts.push(_nextDiscountDetail);
1767
+ appliedDiscountProducts.set(_nextBundleDiscount.id, _nextAppliedProducts);
1768
+ processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1769
+ _id: _nextUniqueId,
1770
+ num: 1,
1771
+ quantity: 1,
1772
+ price: nextDiscountedPrice,
1773
+ total: nextDiscountedPrice,
1774
+ discount_list: [_nextDiscountDetail],
1775
+ processed: true,
1776
+ _discountId: _nextBundleDiscount.id
1777
+ }));
1778
+ continueSplitIndex++;
1779
+ }
1780
+ remainingNum -= nextSplitCount;
1303
1781
  }
1304
1782
  } else {
1305
- var _selectedDiscount3$me, _selectedDiscount3$me2, _flatItem$parentProdu9;
1306
- // 折扣卡:不拆分数量,直接应用
1307
- var _selectedDiscount3 = selectedDiscountCard || applicableDiscounts[0];
1308
- usedDiscounts.set(_selectedDiscount3.id, true);
1783
+ var _currentBundleDiscoun3, _currentBundleDiscoun4, _flatItem$parentProdu10;
1784
+ // 不拆分:直接应用折扣
1785
+ var _currentBundleDiscount = selectedDiscountCard || applicableDiscounts[0];
1786
+ usedDiscounts.set(_currentBundleDiscount.id, true);
1787
+ // 🔥 更新 product_id 使用计数
1788
+ if ((_currentBundleDiscount.tag || _currentBundleDiscount.type) === 'good_pass') {
1789
+ var _currentCount2 = usedProductIdCounts.get(_currentBundleDiscount.product_id) || 0;
1790
+ usedProductIdCounts.set(_currentBundleDiscount.product_id, _currentCount2 + 1);
1791
+ }
1792
+ // 🔥 更新折扣卡 applicableProductLimit 使用计数(不拆分时按商品数量计数)
1793
+ var noSplitDiscountType = _currentBundleDiscount.tag || _currentBundleDiscount.type;
1794
+ if (['discount_card', 'product_discount_card'].includes(noSplitDiscountType)) {
1795
+ var bundleQuantity = product.num || 1;
1796
+ var currentNoSplitCount = usedDiscountCardLimitCounts.get(_currentBundleDiscount.id) || 0;
1797
+ usedDiscountCardLimitCounts.set(_currentBundleDiscount.id, currentNoSplitCount + bundleQuantity);
1798
+ }
1309
1799
  var _productOriginTotal = product.original_price || product.price || 0;
1310
1800
 
1311
1801
  // 🔥 检查是否是 order_level 固定金额折扣卡
1312
- var _isOrderLevel = isOrderLevelFixedAmountDiscount(_selectedDiscount3);
1313
- var _orderLevelAllocation = _isOrderLevel ? orderLevelDiscountAllocations.get(_selectedDiscount3.id) : null;
1802
+ var _isOrderLevel = isOrderLevelFixedAmountDiscount(selectedDiscount);
1803
+ var _orderLevelAllocation = _isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount.id) : null;
1314
1804
  var _productAllocation = _orderLevelAllocation === null || _orderLevelAllocation === void 0 ? void 0 : _orderLevelAllocation.get(flatItem._id);
1315
- var _targetProductTotal;
1805
+ var targetProductTotal;
1316
1806
  var fixedAmountPerItem;
1317
1807
  var _productDiscountDifference;
1318
1808
  if (_isOrderLevel && _productAllocation) {
1319
1809
  // order_level:使用预计算的单价折扣金额(已经是单价,无需再除以数量)
1320
1810
  fixedAmountPerItem = _productAllocation.discountAmount;
1321
1811
  _productDiscountDifference = _productAllocation.difference;
1322
- _targetProductTotal = Math.max(new Decimal(_productOriginTotal).minus(fixedAmountPerItem).toNumber(), 0);
1812
+ targetProductTotal = Math.max(new Decimal(_productOriginTotal).minus(fixedAmountPerItem).toNumber(), 0);
1323
1813
  } else {
1324
1814
  // item_level 或其他类型:使用原有逻辑
1325
- _targetProductTotal = getDiscountAmount(_selectedDiscount3, _productOriginTotal, _productOriginTotal);
1326
- fixedAmountPerItem = new Decimal(_productOriginTotal).minus(_targetProductTotal).toNumber();
1815
+ targetProductTotal = getDiscountAmount(_currentBundleDiscount, _productOriginTotal, _productOriginTotal);
1816
+ fixedAmountPerItem = new Decimal(_productOriginTotal).minus(targetProductTotal).toNumber();
1327
1817
  }
1328
1818
 
1819
+ // 计算实际折扣金额
1820
+ var bundleActualDiscountAmount = new Decimal(_productOriginTotal).minus(targetProductTotal).toNumber();
1821
+
1329
1822
  // 🔥 使用当前的 _id 作为唯一标识
1330
1823
  var _uniqueId = flatItem._id;
1331
1824
  var _discountDetail2 = {
1332
- amount: fixedAmountPerItem * (product.num || 1),
1333
- type: _selectedDiscount3.tag === 'product_discount_card' ? 'discount_card' : _selectedDiscount3.tag,
1825
+ amount: bundleActualDiscountAmount * (product.num || 1),
1826
+ type: _currentBundleDiscount.tag === 'product_discount_card' ? 'discount_card' : _currentBundleDiscount.tag,
1334
1827
  discount: {
1335
- discount_card_type: _selectedDiscount3 === null || _selectedDiscount3 === void 0 || (_selectedDiscount3$me = _selectedDiscount3.metadata) === null || _selectedDiscount3$me === void 0 ? void 0 : _selectedDiscount3$me.discount_card_type,
1336
- fixed_amount: fixedAmountPerItem,
1337
- discount_calculation_mode: _selectedDiscount3 === null || _selectedDiscount3 === void 0 || (_selectedDiscount3$me2 = _selectedDiscount3.metadata) === null || _selectedDiscount3$me2 === void 0 ? void 0 : _selectedDiscount3$me2.discount_calculation_mode,
1338
- resource_id: _selectedDiscount3.id,
1339
- title: _selectedDiscount3.format_title,
1828
+ discount_card_type: _currentBundleDiscount === null || _currentBundleDiscount === void 0 || (_currentBundleDiscoun3 = _currentBundleDiscount.metadata) === null || _currentBundleDiscoun3 === void 0 ? void 0 : _currentBundleDiscoun3.discount_card_type,
1829
+ fixed_amount: bundleActualDiscountAmount,
1830
+ discount_calculation_mode: _currentBundleDiscount === null || _currentBundleDiscount === void 0 || (_currentBundleDiscoun4 = _currentBundleDiscount.metadata) === null || _currentBundleDiscoun4 === void 0 ? void 0 : _currentBundleDiscoun4.discount_calculation_mode,
1831
+ resource_id: _currentBundleDiscount.id,
1832
+ title: _currentBundleDiscount.format_title,
1340
1833
  original_amount: product.original_price,
1341
1834
  product_id: product.id,
1342
- percent: _selectedDiscount3.par_value
1835
+ percent: _currentBundleDiscount.par_value,
1836
+ discount_product_id: _currentBundleDiscount.product_id
1343
1837
  },
1344
1838
  metadata: _objectSpread({
1345
1839
  // 🔥 使用唯一的 _id
1346
1840
  custom_product_bundle_map_id: _uniqueId,
1347
- discount_rule_uncheck_flag: _selectedDiscount3 === null || _selectedDiscount3 === void 0 ? void 0 : _selectedDiscount3.discount_rule_uncheck_flag,
1841
+ discount_rule_uncheck_flag: selectedDiscount === null || selectedDiscount === void 0 ? void 0 : selectedDiscount.discount_rule_uncheck_flag,
1348
1842
  num: product.num || 1
1349
1843
  }, _productDiscountDifference !== undefined && {
1350
1844
  product_discount_difference: _productDiscountDifference
1351
1845
  }),
1352
- _num: (product.num || 1) * ((flatItem === null || flatItem === void 0 || (_flatItem$parentProdu9 = flatItem.parentProduct) === null || _flatItem$parentProdu9 === void 0 ? void 0 : _flatItem$parentProdu9.num) || 1)
1846
+ config: _currentBundleDiscount === null || _currentBundleDiscount === void 0 ? void 0 : _currentBundleDiscount.config,
1847
+ _num: (product.num || 1) * ((flatItem === null || flatItem === void 0 || (_flatItem$parentProdu10 = flatItem.parentProduct) === null || _flatItem$parentProdu10 === void 0 ? void 0 : _flatItem$parentProdu10.num) || 1)
1353
1848
  };
1354
1849
 
1355
1850
  // 记录实际应用的折扣
1356
- var _appliedProducts2 = appliedDiscountProducts.get(_selectedDiscount3.id) || [];
1851
+ var _appliedProducts2 = appliedDiscountProducts.get(_currentBundleDiscount.id) || [];
1357
1852
  _appliedProducts2.push(_discountDetail2);
1358
- appliedDiscountProducts.set(_selectedDiscount3.id, _appliedProducts2);
1853
+ appliedDiscountProducts.set(_currentBundleDiscount.id, _appliedProducts2);
1359
1854
  processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1360
- total: _targetProductTotal,
1855
+ total: targetProductTotal,
1361
1856
  price: new Decimal(_productOriginTotal || 0).minus(fixedAmountPerItem).toNumber(),
1362
1857
  discount_list: _this3.filterDiscountListByType(flatItem.discount_list, 'promotion').concat([_discountDetail2]),
1363
1858
  processed: true
@@ -1376,8 +1871,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1376
1871
  // 获取主商品处理结果
1377
1872
  var mainProductArr = processedProductsMap.get(product._id);
1378
1873
  if (!mainProductArr || mainProductArr.length === 0) {
1379
- // 如果没有处理结果,返回默认商品
1874
+ // 如果没有处理结果,返回默认商品(还原 option 价格)
1380
1875
  var getDefaultProduct = function getDefaultProduct() {
1876
+ var restoredOptions = restoreOptionPrices(product.options);
1381
1877
  if (product.isClient) {
1382
1878
  return _this3.hooks.setProduct(originProduct, {
1383
1879
  discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion'),
@@ -1387,7 +1883,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1387
1883
  original_price: product.original_price
1388
1884
  },
1389
1885
  bundle: product.bundle,
1390
- options: product.options
1886
+ options: restoredOptions
1391
1887
  }),
1392
1888
  variant: originProduct._productInit.variant,
1393
1889
  original_price: originProduct._productInit.original_price,
@@ -1396,15 +1892,17 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1396
1892
  price: product.price
1397
1893
  },
1398
1894
  bundle: product.bundle,
1399
- options: product.options
1400
- })
1895
+ options: restoredOptions
1896
+ }),
1897
+ options: restoredOptions
1401
1898
  });
1402
1899
  } else {
1403
1900
  return _this3.hooks.setProduct(originProduct, {
1404
1901
  discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion'),
1405
1902
  total: product.total,
1406
1903
  origin_total: product.origin_total,
1407
- price: product.price
1904
+ price: product.price,
1905
+ options: restoreOptionPrices(product.options)
1408
1906
  });
1409
1907
  }
1410
1908
  };
@@ -1480,6 +1978,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1480
1978
  product_id: bundleItem.product_id,
1481
1979
  price: item.price,
1482
1980
  num: item.num,
1981
+ quantity: item.num,
1483
1982
  discount_list: updatedDiscountList
1484
1983
  }));
1485
1984
  });
@@ -1503,6 +2002,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1503
2002
  product_id: bundleItem.product_id,
1504
2003
  price: item.price,
1505
2004
  num: item.num,
2005
+ quantity: item.num,
1506
2006
  discount_list: _updatedDiscountList
1507
2007
  }));
1508
2008
  } else {
@@ -1517,8 +2017,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1517
2017
 
1518
2018
  // 🔥 更新主商品自己的 discount_list 中的 num(quantity=1)
1519
2019
  var updatedMainDiscountList = mainProductData.discount_list.map(function (discount) {
1520
- var _discount$metadata6, _discount$metadata7;
1521
- if (discount !== null && discount !== void 0 && (_discount$metadata6 = discount.metadata) !== null && _discount$metadata6 !== void 0 && _discount$metadata6.custom_product_bundle_map_id) {
2020
+ var _discount$metadata7, _discount$metadata8;
2021
+ if (discount !== null && discount !== void 0 && (_discount$metadata7 = discount.metadata) !== null && _discount$metadata7 !== void 0 && _discount$metadata7.custom_product_bundle_map_id) {
1522
2022
  // bundle的discount_list保持不变
1523
2023
  return discount;
1524
2024
  }
@@ -1526,7 +2026,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1526
2026
  return _objectSpread(_objectSpread({}, discount), {}, {
1527
2027
  // num: 1,
1528
2028
  metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
1529
- custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata7 = discount.metadata) === null || _discount$metadata7 === void 0 ? void 0 : _discount$metadata7.custom_product_bundle_map_id,
2029
+ custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata8 = discount.metadata) === null || _discount$metadata8 === void 0 ? void 0 : _discount$metadata8.custom_product_bundle_map_id,
1530
2030
  num: 1
1531
2031
  })
1532
2032
  });
@@ -1571,8 +2071,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1571
2071
  quantity: 1,
1572
2072
  discount_list: updatedMainDiscountList,
1573
2073
  bundle: newBundleWithDiscount,
1574
- total: new Decimal(newTotalWithDiscount).toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber(),
1575
- origin_total: new Decimal(newOriginTotalWithDiscount).toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber()
2074
+ total: newTotalWithDiscount,
2075
+ origin_total: newOriginTotalWithDiscount
1576
2076
  })));
1577
2077
 
1578
2078
  // 第二个:包含原始bundle (qty=原quantity-1)
@@ -1591,8 +2091,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1591
2091
 
1592
2092
  // 🔥 更新主商品自己的 discount_list 中的 num(quantity=原quantity-1)
1593
2093
  var updatedMainDiscountListOriginal = mainProductData.discount_list.map(function (discount) {
1594
- var _discount$metadata8, _discount$metadata9;
1595
- if (discount !== null && discount !== void 0 && (_discount$metadata8 = discount.metadata) !== null && _discount$metadata8 !== void 0 && _discount$metadata8.custom_product_bundle_map_id) {
2094
+ var _discount$metadata9, _discount$metadata10;
2095
+ if (discount !== null && discount !== void 0 && (_discount$metadata9 = discount.metadata) !== null && _discount$metadata9 !== void 0 && _discount$metadata9.custom_product_bundle_map_id) {
1596
2096
  // bundle的discount_list保持不变
1597
2097
  return discount;
1598
2098
  }
@@ -1600,7 +2100,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1600
2100
  return _objectSpread(_objectSpread({}, discount), {}, {
1601
2101
  metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
1602
2102
  num: mainProductQuantity - 1,
1603
- custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata9 = discount.metadata) === null || _discount$metadata9 === void 0 ? void 0 : _discount$metadata9.custom_product_bundle_map_id
2103
+ custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata10 = discount.metadata) === null || _discount$metadata10 === void 0 ? void 0 : _discount$metadata10.custom_product_bundle_map_id
1604
2104
  })
1605
2105
  // num: mainProductQuantity - 1,
1606
2106
  });
@@ -1667,11 +2167,11 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1667
2167
  processedBundleItems.forEach(function (item) {
1668
2168
  // 🔥 更新 discount_list 中的 num,使其与拆分后的 item.num 一致
1669
2169
  var updatedDiscountList = (item.discount_list || []).map(function (discount) {
1670
- var _discount$metadata10;
2170
+ var _discount$metadata11;
1671
2171
  return _objectSpread(_objectSpread({}, discount), {}, {
1672
2172
  metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
1673
2173
  num: item.num,
1674
- custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata10 = discount.metadata) === null || _discount$metadata10 === void 0 ? void 0 : _discount$metadata10.custom_product_bundle_map_id
2174
+ custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata11 = discount.metadata) === null || _discount$metadata11 === void 0 ? void 0 : _discount$metadata11.custom_product_bundle_map_id
1675
2175
  })
1676
2176
  // num: item.num, // 使用拆分后的 num
1677
2177
  });
@@ -1681,7 +2181,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1681
2181
  product_id: bundleItem.product_id,
1682
2182
  price: item.price,
1683
2183
  num: item.num,
1684
- discount_list: updatedDiscountList
2184
+ quantity: item.num,
2185
+ discount_list: updatedDiscountList,
2186
+ bundle_selling_price: bundleItem.bundle_selling_price !== undefined ? item.price : undefined
1685
2187
  }));
1686
2188
  });
1687
2189
  }
@@ -1719,13 +2221,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1719
2221
 
1720
2222
  // 累加bundle的价格(只累加一次)
1721
2223
  if (newBundle.length > 0) {
1722
- newBundle.forEach(function (item) {
1723
- newTotal += Number(item.price) * Number(item.num);
1724
- });
1725
-
1726
- // 计算原始总价(不考虑折扣)
1727
2224
  newBundle.forEach(function (item) {
1728
2225
  var _item$discount_list3;
2226
+ newTotal += Number(item.price) * Number(item.num);
1729
2227
  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;
1730
2228
  newOriginTotal += Number(originalPrice) * Number(item.num);
1731
2229
  });
@@ -1740,8 +2238,6 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1740
2238
  return accumulator.add(currentPrice.mul(currentNum));
1741
2239
  }, new Decimal(newTotal)).toNumber();
1742
2240
  }
1743
- newTotal = new Decimal(newTotal).toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber();
1744
- newOriginTotal = new Decimal(newOriginTotal).toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber();
1745
2241
 
1746
2242
  // 生成最终的主商品
1747
2243
  result.push(_this3.hooks.setProduct(mainProduct, _objectSpread(_objectSpread({}, mainProductData), {}, {
@@ -1849,14 +2345,14 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1849
2345
  var ruleType = usageRules.type;
1850
2346
  // 套餐适用范围配置
1851
2347
  var packageScope = usageRules === null || usageRules === void 0 ? void 0 : usageRules.package_scope;
1852
- var _ref9 = packageScope || {},
1853
- scopeType = _ref9.type,
1854
- _ref9$exclude_bundle_ = _ref9.exclude_bundle_product_ids,
1855
- exclude_bundle_product_ids = _ref9$exclude_bundle_ === void 0 ? [] : _ref9$exclude_bundle_,
1856
- _ref9$include_bundle_ = _ref9.include_bundle_product_ids,
1857
- include_bundle_product_ids = _ref9$include_bundle_ === void 0 ? [] : _ref9$include_bundle_,
1858
- _ref9$filter = _ref9.filter,
1859
- filter = _ref9$filter === void 0 ? 0 : _ref9$filter;
2348
+ var _ref14 = packageScope || {},
2349
+ scopeType = _ref14.type,
2350
+ _ref14$exclude_bundle = _ref14.exclude_bundle_product_ids,
2351
+ exclude_bundle_product_ids = _ref14$exclude_bundle === void 0 ? [] : _ref14$exclude_bundle,
2352
+ _ref14$include_bundle = _ref14.include_bundle_product_ids,
2353
+ include_bundle_product_ids = _ref14$include_bundle === void 0 ? [] : _ref14$include_bundle,
2354
+ _ref14$filter = _ref14.filter,
2355
+ filter = _ref14$filter === void 0 ? 0 : _ref14$filter;
1860
2356
  var isMainProduct = flatItem.type === 'main'; // 单独购买
1861
2357
  var isBundleItem = flatItem.type === 'bundle'; // 套餐中购买
1862
2358
 
@@ -1871,12 +2367,12 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1871
2367
  return true; // 单独购买时可用
1872
2368
  }
1873
2369
  if (isBundleItem) {
1874
- var _flatItem$bundleItem9, _flatItem$bundleItem10, _flatItem$originProdu, _flatItem$parentProdu10;
2370
+ var _flatItem$bundleItem9, _flatItem$bundleItem10, _flatItem$originProdu, _flatItem$parentProdu11;
1875
2371
  // 套餐中购买时,判断是否为原价
1876
2372
  var priceType = (_flatItem$bundleItem9 = flatItem.bundleItem) === null || _flatItem$bundleItem9 === void 0 ? void 0 : _flatItem$bundleItem9.price_type;
1877
2373
  var priceTypeExt = (_flatItem$bundleItem10 = flatItem.bundleItem) === null || _flatItem$bundleItem10 === void 0 ? void 0 : _flatItem$bundleItem10.price_type_ext;
1878
2374
  // 主商品id
1879
- var mainProductId = (flatItem === null || flatItem === void 0 || (_flatItem$originProdu = flatItem.originProduct) === null || _flatItem$originProdu === void 0 || (_flatItem$originProdu = _flatItem$originProdu._productOrigin) === null || _flatItem$originProdu === void 0 ? void 0 : _flatItem$originProdu.id) || (flatItem === null || flatItem === void 0 || (_flatItem$parentProdu10 = flatItem.parentProduct) === null || _flatItem$parentProdu10 === void 0 ? void 0 : _flatItem$parentProdu10.id) || 0;
2375
+ var mainProductId = (flatItem === null || flatItem === void 0 || (_flatItem$originProdu = flatItem.originProduct) === null || _flatItem$originProdu === void 0 || (_flatItem$originProdu = _flatItem$originProdu._productOrigin) === null || _flatItem$originProdu === void 0 ? void 0 : _flatItem$originProdu.id) || (flatItem === null || flatItem === void 0 || (_flatItem$parentProdu11 = flatItem.parentProduct) === null || _flatItem$parentProdu11 === void 0 ? void 0 : _flatItem$parentProdu11.id) || 0;
1880
2376
  // original_price 对应:
1881
2377
  // 1. price_type: "markup" && price_type_ext: "product_price"
1882
2378
  // markup_price 对应: