@pisell/pisellos 2.1.126 → 2.1.128
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.
- package/dist/model/strategy/adapter/itemRule/adapter.js +6 -2
- package/dist/model/strategy/adapter/itemRule/examples.d.ts +15 -0
- package/dist/model/strategy/adapter/itemRule/examples.js +68 -1
- package/dist/model/strategy/adapter/itemRule/index.d.ts +1 -1
- package/dist/model/strategy/adapter/itemRule/index.js +1 -1
- package/dist/model/strategy/adapter/itemRule/type.d.ts +9 -0
- package/dist/modules/Order/index.d.ts +1 -1
- package/dist/modules/Order/index.js +9 -40
- package/dist/modules/Order/utils.d.ts +25 -1
- package/dist/modules/Order/utils.js +88 -12
- package/dist/modules/SalesSummary/types.d.ts +2 -1
- package/dist/modules/SalesSummary/utils.js +10 -10
- package/dist/solution/BookingByStep/index.d.ts +2 -2
- package/dist/solution/ScanOrder/index.d.ts +5 -0
- package/dist/solution/ScanOrder/index.js +181 -62
- package/dist/solution/ScanOrder/types.d.ts +19 -5
- package/dist/solution/ScanOrder/utils.d.ts +14 -0
- package/dist/solution/ScanOrder/utils.js +138 -63
- package/dist/solution/VenueBooking/index.js +42 -44
- package/lib/model/strategy/adapter/itemRule/adapter.js +10 -2
- package/lib/model/strategy/adapter/itemRule/examples.d.ts +15 -0
- package/lib/model/strategy/adapter/itemRule/examples.js +47 -0
- package/lib/model/strategy/adapter/itemRule/index.d.ts +1 -1
- package/lib/model/strategy/adapter/itemRule/index.js +2 -0
- package/lib/model/strategy/adapter/itemRule/type.d.ts +9 -0
- package/lib/model/strategy/adapter/promotion/index.js +0 -49
- package/lib/modules/Order/index.d.ts +1 -1
- package/lib/modules/Order/index.js +8 -41
- package/lib/modules/Order/utils.d.ts +25 -1
- package/lib/modules/Order/utils.js +66 -5
- package/lib/modules/SalesSummary/types.d.ts +2 -1
- package/lib/modules/SalesSummary/utils.js +2 -2
- package/lib/solution/BookingByStep/index.d.ts +2 -2
- package/lib/solution/ScanOrder/index.d.ts +5 -0
- package/lib/solution/ScanOrder/index.js +78 -19
- package/lib/solution/ScanOrder/types.d.ts +19 -5
- package/lib/solution/ScanOrder/utils.d.ts +14 -0
- package/lib/solution/ScanOrder/utils.js +82 -20
- package/lib/solution/VenueBooking/index.js +11 -16
- package/package.json +1 -1
|
@@ -170,28 +170,22 @@ export function buildQuantityLimitIndex(limits) {
|
|
|
170
170
|
try {
|
|
171
171
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
172
172
|
var limit = _step2.value;
|
|
173
|
-
var
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
productLimitMap.set(productId, [].concat(_toConsumableArray(existed), [limit]));
|
|
190
|
-
}
|
|
191
|
-
} catch (err) {
|
|
192
|
-
_iterator3.e(err);
|
|
193
|
-
} finally {
|
|
194
|
-
_iterator3.f();
|
|
173
|
+
var targets = limit.targets || [];
|
|
174
|
+
// 多目标规则(OR 组)只做购物车聚合校验,不下发到单品维度,
|
|
175
|
+
// 避免 UI 把「组内至少 1 份」误当作每款商品各自的 min,锁死减号按钮。
|
|
176
|
+
if (targets.length !== 1) continue;
|
|
177
|
+
var target = targets[0];
|
|
178
|
+
var productId = Number(target.product_id);
|
|
179
|
+
if (!Number.isFinite(productId) || productId <= 0) continue;
|
|
180
|
+
var variantId = Number(target.product_variant_id);
|
|
181
|
+
var hasVariant = Number.isFinite(variantId) && variantId > 0;
|
|
182
|
+
if (hasVariant) {
|
|
183
|
+
var exactKey = buildProductKey(productId, variantId);
|
|
184
|
+
var existed = exactLimitMap.get(exactKey) || [];
|
|
185
|
+
exactLimitMap.set(exactKey, [].concat(_toConsumableArray(existed), [limit]));
|
|
186
|
+
} else {
|
|
187
|
+
var _existed = productLimitMap.get(productId) || [];
|
|
188
|
+
productLimitMap.set(productId, [].concat(_toConsumableArray(_existed), [limit]));
|
|
195
189
|
}
|
|
196
190
|
}
|
|
197
191
|
} catch (err) {
|
|
@@ -219,40 +213,81 @@ export function aggregateItemRuleLimit(matchedLimits) {
|
|
|
219
213
|
var remainingMax;
|
|
220
214
|
var exact;
|
|
221
215
|
var mustInclude = false;
|
|
222
|
-
|
|
223
|
-
|
|
216
|
+
|
|
217
|
+
// 聚合 validationMessage 按 min / max 两个方向分别输出:
|
|
218
|
+
// - maxValidationMessage:触发"当前 max / remainingMax / exact"的那条规则的文案
|
|
219
|
+
// - minValidationMessage:触发"当前 min / exact"的那条规则的文案
|
|
220
|
+
// 各自再回退到其他带文案的规则(最后回退到第一条非空 validationMessage)。
|
|
221
|
+
// 前端可根据"加号/减号被拦"的方向取对应文案。
|
|
222
|
+
var maxSourceLimit;
|
|
223
|
+
var remainingMaxSourceLimit;
|
|
224
|
+
var exactSourceLimit;
|
|
225
|
+
var minSourceLimit;
|
|
226
|
+
var firstMessagedLimit;
|
|
227
|
+
var _iterator3 = _createForOfIteratorHelper(matchedLimits),
|
|
228
|
+
_step3;
|
|
224
229
|
try {
|
|
225
|
-
for (
|
|
226
|
-
var limit =
|
|
230
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
231
|
+
var limit = _step3.value;
|
|
227
232
|
if (typeof limit.requiredMin === 'number' && Number.isFinite(limit.requiredMin)) {
|
|
228
|
-
|
|
233
|
+
if (min === undefined || limit.requiredMin > min) {
|
|
234
|
+
min = limit.requiredMin;
|
|
235
|
+
minSourceLimit = limit;
|
|
236
|
+
}
|
|
229
237
|
}
|
|
230
238
|
if (typeof limit.requiredMax === 'number' && Number.isFinite(limit.requiredMax)) {
|
|
231
|
-
|
|
239
|
+
if (max === undefined || limit.requiredMax < max) {
|
|
240
|
+
max = limit.requiredMax;
|
|
241
|
+
maxSourceLimit = limit;
|
|
242
|
+
}
|
|
232
243
|
}
|
|
233
244
|
if (typeof limit.remainingMax === 'number' && Number.isFinite(limit.remainingMax)) {
|
|
234
|
-
|
|
245
|
+
if (remainingMax === undefined || limit.remainingMax < remainingMax) {
|
|
246
|
+
remainingMax = limit.remainingMax;
|
|
247
|
+
remainingMaxSourceLimit = limit;
|
|
248
|
+
}
|
|
235
249
|
}
|
|
236
250
|
if (typeof limit.requiredExact === 'number' && Number.isFinite(limit.requiredExact)) {
|
|
237
251
|
exact = limit.requiredExact;
|
|
252
|
+
exactSourceLimit = limit;
|
|
238
253
|
}
|
|
239
254
|
mustInclude = mustInclude || Boolean(limit.mustInclude);
|
|
255
|
+
if (!firstMessagedLimit && limit.validationMessage) {
|
|
256
|
+
firstMessagedLimit = limit;
|
|
257
|
+
}
|
|
240
258
|
}
|
|
241
259
|
} catch (err) {
|
|
242
|
-
|
|
260
|
+
_iterator3.e(err);
|
|
243
261
|
} finally {
|
|
244
|
-
|
|
262
|
+
_iterator3.f();
|
|
245
263
|
}
|
|
246
264
|
if (typeof exact === 'number' && Number.isFinite(exact)) {
|
|
247
265
|
min = exact;
|
|
248
266
|
max = exact;
|
|
249
267
|
}
|
|
268
|
+
var maxMessageSource = maxSourceLimit || remainingMaxSourceLimit || exactSourceLimit || firstMessagedLimit;
|
|
269
|
+
var minMessageSource = minSourceLimit || exactSourceLimit || firstMessagedLimit;
|
|
270
|
+
var maxValidationMessage = maxMessageSource === null || maxMessageSource === void 0 ? void 0 : maxMessageSource.validationMessage;
|
|
271
|
+
var rawMaxValidationMessage = maxMessageSource === null || maxMessageSource === void 0 ? void 0 : maxMessageSource.rawValidationMessage;
|
|
272
|
+
var minValidationMessage = minMessageSource === null || minMessageSource === void 0 ? void 0 : minMessageSource.validationMessage;
|
|
273
|
+
var rawMinValidationMessage = minMessageSource === null || minMessageSource === void 0 ? void 0 : minMessageSource.rawValidationMessage;
|
|
274
|
+
|
|
275
|
+
// validationMessage / rawValidationMessage 保留为"最严格限制"的聚合文案,
|
|
276
|
+
// 便于旧消费者(只关心 max 侧)不破坏。优先 max → min。
|
|
277
|
+
var validationMessage = maxValidationMessage !== null && maxValidationMessage !== void 0 ? maxValidationMessage : minValidationMessage;
|
|
278
|
+
var rawValidationMessage = rawMaxValidationMessage !== null && rawMaxValidationMessage !== void 0 ? rawMaxValidationMessage : rawMinValidationMessage;
|
|
250
279
|
return {
|
|
251
280
|
min: min,
|
|
252
281
|
max: max,
|
|
253
282
|
remainingMax: remainingMax,
|
|
254
283
|
exact: exact,
|
|
255
|
-
mustInclude: mustInclude
|
|
284
|
+
mustInclude: mustInclude,
|
|
285
|
+
validationMessage: validationMessage,
|
|
286
|
+
rawValidationMessage: rawValidationMessage,
|
|
287
|
+
maxValidationMessage: maxValidationMessage,
|
|
288
|
+
rawMaxValidationMessage: rawMaxValidationMessage,
|
|
289
|
+
minValidationMessage: minValidationMessage,
|
|
290
|
+
rawMinValidationMessage: rawMinValidationMessage
|
|
256
291
|
};
|
|
257
292
|
}
|
|
258
293
|
export function buildItemRuleBusinessData(params) {
|
|
@@ -300,11 +335,11 @@ export function buildItemRuleBusinessData(params) {
|
|
|
300
335
|
export function attachItemRuleLimitsToTopLevelProducts(productList, limits) {
|
|
301
336
|
if (!Array.isArray(productList)) return productList;
|
|
302
337
|
var limitIndex = buildQuantityLimitIndex(limits || []);
|
|
303
|
-
var
|
|
304
|
-
|
|
338
|
+
var _iterator4 = _createForOfIteratorHelper(productList),
|
|
339
|
+
_step4;
|
|
305
340
|
try {
|
|
306
|
-
for (
|
|
307
|
-
var item =
|
|
341
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
342
|
+
var item = _step4.value;
|
|
308
343
|
if (!item || _typeof(item) !== 'object') continue;
|
|
309
344
|
var productItem = item;
|
|
310
345
|
var productId = getTopLevelProductId(productItem);
|
|
@@ -323,9 +358,9 @@ export function attachItemRuleLimitsToTopLevelProducts(productList, limits) {
|
|
|
323
358
|
}
|
|
324
359
|
}
|
|
325
360
|
} catch (err) {
|
|
326
|
-
|
|
361
|
+
_iterator4.e(err);
|
|
327
362
|
} finally {
|
|
328
|
-
|
|
363
|
+
_iterator4.f();
|
|
329
364
|
}
|
|
330
365
|
return productList;
|
|
331
366
|
}
|
|
@@ -363,8 +398,14 @@ export function normalizeOrderProduct(product) {
|
|
|
363
398
|
if (product.identity_key && !metadata.unique_identification_number) {
|
|
364
399
|
metadata.unique_identification_number = product.identity_key;
|
|
365
400
|
}
|
|
366
|
-
|
|
401
|
+
|
|
402
|
+
// selling_price:券后成交单价;original_price:券前店铺售价。
|
|
403
|
+
// 初次加购时两者相等(入口层应保证 caller 传的 original_price == selling_price);
|
|
404
|
+
// 券应用后由 Rules 引擎只改动 selling_price,保留 original_price 以便还原 / 展示划线对比。
|
|
405
|
+
// 注意:这里 caller 若显式传入了 original_price(例如 Rules 回写或单测场景),要尊重该值,
|
|
406
|
+
// 让券后状态能正确通过再次 normalize。
|
|
367
407
|
var resolvedSellingPrice = product.selling_price || '0.00';
|
|
408
|
+
var resolvedOriginalPrice = product.original_price || resolvedSellingPrice;
|
|
368
409
|
if (metadata.main_product_original_price === undefined) {
|
|
369
410
|
metadata.main_product_original_price = resolvedOriginalPrice;
|
|
370
411
|
}
|
|
@@ -372,14 +413,14 @@ export function normalizeOrderProduct(product) {
|
|
|
372
413
|
metadata.main_product_selling_price = resolvedSellingPrice;
|
|
373
414
|
}
|
|
374
415
|
if (metadata.source_product_price === undefined) {
|
|
375
|
-
var _product$_origin$
|
|
376
|
-
metadata.source_product_price = (_product$_origin$
|
|
416
|
+
var _ref, _product$_origin$pric, _product$_origin, _product$_origin2;
|
|
417
|
+
metadata.source_product_price = (_ref = (_product$_origin$pric = (_product$_origin = product._origin) === null || _product$_origin === void 0 ? void 0 : _product$_origin.price) !== null && _product$_origin$pric !== void 0 ? _product$_origin$pric : (_product$_origin2 = product._origin) === null || _product$_origin2 === void 0 ? void 0 : _product$_origin2.base_price) !== null && _ref !== void 0 ? _ref : resolvedSellingPrice;
|
|
377
418
|
}
|
|
378
419
|
var normalizedBundle = (product.product_bundle || []).map(function (item) {
|
|
379
|
-
var
|
|
420
|
+
var _ref2, _item$bundle_selling_, _ref3, _ref4, _item$custom_price;
|
|
380
421
|
return _objectSpread(_objectSpread({}, item), {}, {
|
|
381
|
-
bundle_selling_price: (
|
|
382
|
-
custom_price: (
|
|
422
|
+
bundle_selling_price: (_ref2 = (_item$bundle_selling_ = item.bundle_selling_price) !== null && _item$bundle_selling_ !== void 0 ? _item$bundle_selling_ : item.price) !== null && _ref2 !== void 0 ? _ref2 : '0.00',
|
|
423
|
+
custom_price: (_ref3 = (_ref4 = (_item$custom_price = item.custom_price) !== null && _item$custom_price !== void 0 ? _item$custom_price : item.bundle_selling_price) !== null && _ref4 !== void 0 ? _ref4 : item.price) !== null && _ref3 !== void 0 ? _ref3 : '0.00'
|
|
383
424
|
});
|
|
384
425
|
});
|
|
385
426
|
return {
|
|
@@ -391,7 +432,6 @@ export function normalizeOrderProduct(product) {
|
|
|
391
432
|
product_option_item: product.product_option_item || [],
|
|
392
433
|
selling_price: resolvedSellingPrice,
|
|
393
434
|
original_price: resolvedOriginalPrice,
|
|
394
|
-
payment_price: product.payment_price || '0.00',
|
|
395
435
|
tax_fee: product.tax_fee || '0.00',
|
|
396
436
|
is_charge_tax: (_product$is_charge_ta = product.is_charge_tax) !== null && _product$is_charge_ta !== void 0 ? _product$is_charge_ta : 0,
|
|
397
437
|
discount_list: product.discount_list || [],
|
|
@@ -407,33 +447,33 @@ export function normalizeOrderProduct(product) {
|
|
|
407
447
|
export function collectLinkProductIdsFromReservationRules(rules) {
|
|
408
448
|
if (!Array.isArray(rules)) return [];
|
|
409
449
|
var ids = [];
|
|
410
|
-
var
|
|
411
|
-
|
|
450
|
+
var _iterator5 = _createForOfIteratorHelper(rules),
|
|
451
|
+
_step5;
|
|
412
452
|
try {
|
|
413
|
-
for (
|
|
414
|
-
var entry =
|
|
453
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
454
|
+
var entry = _step5.value;
|
|
415
455
|
if (!entry || _typeof(entry) !== 'object') continue;
|
|
416
456
|
var rec = entry;
|
|
417
457
|
if (rec.type !== 'link') continue;
|
|
418
458
|
if (!Array.isArray(rec.value)) continue;
|
|
419
|
-
var
|
|
420
|
-
|
|
459
|
+
var _iterator6 = _createForOfIteratorHelper(rec.value),
|
|
460
|
+
_step6;
|
|
421
461
|
try {
|
|
422
|
-
for (
|
|
423
|
-
var v =
|
|
462
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
463
|
+
var v = _step6.value;
|
|
424
464
|
var n = Number(v);
|
|
425
465
|
if (Number.isFinite(n) && n > 0) ids.push(Math.floor(n));
|
|
426
466
|
}
|
|
427
467
|
} catch (err) {
|
|
428
|
-
|
|
468
|
+
_iterator6.e(err);
|
|
429
469
|
} finally {
|
|
430
|
-
|
|
470
|
+
_iterator6.f();
|
|
431
471
|
}
|
|
432
472
|
}
|
|
433
473
|
} catch (err) {
|
|
434
|
-
|
|
474
|
+
_iterator5.e(err);
|
|
435
475
|
} finally {
|
|
436
|
-
|
|
476
|
+
_iterator5.f();
|
|
437
477
|
}
|
|
438
478
|
return _toConsumableArray(new Set(ids));
|
|
439
479
|
}
|
|
@@ -442,20 +482,20 @@ export function collectLinkProductIdsFromReservationRules(rules) {
|
|
|
442
482
|
* 返回列表中第一个带有效 duration.value(分钟)的商品时长。
|
|
443
483
|
*/
|
|
444
484
|
export function pickFirstDurationMinutesFromProducts(products) {
|
|
445
|
-
var
|
|
446
|
-
|
|
485
|
+
var _iterator7 = _createForOfIteratorHelper(products),
|
|
486
|
+
_step7;
|
|
447
487
|
try {
|
|
448
|
-
for (
|
|
488
|
+
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
449
489
|
var _product$duration;
|
|
450
|
-
var product =
|
|
490
|
+
var product = _step7.value;
|
|
451
491
|
var value = product === null || product === void 0 || (_product$duration = product.duration) === null || _product$duration === void 0 ? void 0 : _product$duration.value;
|
|
452
492
|
var n = Number(value);
|
|
453
493
|
if (Number.isFinite(n) && n > 0) return Math.floor(n);
|
|
454
494
|
}
|
|
455
495
|
} catch (err) {
|
|
456
|
-
|
|
496
|
+
_iterator7.e(err);
|
|
457
497
|
} finally {
|
|
458
|
-
|
|
498
|
+
_iterator7.f();
|
|
459
499
|
}
|
|
460
500
|
return undefined;
|
|
461
501
|
}
|
|
@@ -466,4 +506,39 @@ export function hasCustomCapacityProduct(products) {
|
|
|
466
506
|
var _p$capacity;
|
|
467
507
|
return (p === null || p === void 0 || (_p$capacity = p.capacity) === null || _p$capacity === void 0 ? void 0 : _p$capacity.type) === 'custom';
|
|
468
508
|
});
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* 在商品列表中找到第一个 `capacity.type === 'custom'` 的商品,取其 `custom` 数组第一项的 min/max。
|
|
513
|
+
* 仅返回有限数字字段;若均无法解析则返回 `undefined`。
|
|
514
|
+
*/
|
|
515
|
+
export function pickFirstCustomCapacityPaxBounds(products) {
|
|
516
|
+
var _iterator8 = _createForOfIteratorHelper(products),
|
|
517
|
+
_step8;
|
|
518
|
+
try {
|
|
519
|
+
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
520
|
+
var p = _step8.value;
|
|
521
|
+
var cap = p === null || p === void 0 ? void 0 : p.capacity;
|
|
522
|
+
if (!cap || cap.type !== 'custom') continue;
|
|
523
|
+
if (!Array.isArray(cap.custom) || cap.custom.length === 0) continue;
|
|
524
|
+
var row = cap.custom[0];
|
|
525
|
+
if (!row || _typeof(row) !== 'object') continue;
|
|
526
|
+
var raw = row;
|
|
527
|
+
var out = {};
|
|
528
|
+
if (raw.min !== null && raw.min !== undefined && raw.min !== '') {
|
|
529
|
+
var min = Number(raw.min);
|
|
530
|
+
if (Number.isFinite(min)) out.min = min;
|
|
531
|
+
}
|
|
532
|
+
if (raw.max !== null && raw.max !== undefined && raw.max !== '') {
|
|
533
|
+
var max = Number(raw.max);
|
|
534
|
+
if (Number.isFinite(max)) out.max = max;
|
|
535
|
+
}
|
|
536
|
+
if (out.min !== undefined || out.max !== undefined) return out;
|
|
537
|
+
}
|
|
538
|
+
} catch (err) {
|
|
539
|
+
_iterator8.e(err);
|
|
540
|
+
} finally {
|
|
541
|
+
_iterator8.f();
|
|
542
|
+
}
|
|
543
|
+
return undefined;
|
|
469
544
|
}
|
|
@@ -1446,7 +1446,6 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
1446
1446
|
num: 1,
|
|
1447
1447
|
selling_price: group.totalPrice,
|
|
1448
1448
|
original_price: group.totalPrice,
|
|
1449
|
-
payment_price: group.totalPrice,
|
|
1450
1449
|
is_charge_tax: (_venueProduct$is_char = venueProduct === null || venueProduct === void 0 ? void 0 : venueProduct.is_charge_tax) !== null && _venueProduct$is_char !== void 0 ? _venueProduct$is_char : 0,
|
|
1451
1450
|
metadata: {
|
|
1452
1451
|
venue_booking: true,
|
|
@@ -1699,7 +1698,7 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
1699
1698
|
var merged = mergeConsecutiveSlots(updatedSlots);
|
|
1700
1699
|
if (merged.length === 1) {
|
|
1701
1700
|
product.selling_price = merged[0].totalPrice;
|
|
1702
|
-
product.
|
|
1701
|
+
product.original_price = merged[0].totalPrice;
|
|
1703
1702
|
product.metadata.price_breakdown = buildPriceBreakdown({
|
|
1704
1703
|
group: merged[0],
|
|
1705
1704
|
productId: mapping.productId,
|
|
@@ -1715,7 +1714,7 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
1715
1714
|
});
|
|
1716
1715
|
if (quotationPrice !== null) {
|
|
1717
1716
|
product.selling_price = quotationPrice;
|
|
1718
|
-
product.
|
|
1717
|
+
product.original_price = quotationPrice;
|
|
1719
1718
|
}
|
|
1720
1719
|
}
|
|
1721
1720
|
};
|
|
@@ -1793,7 +1792,7 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
1793
1792
|
key: "setDiscountSelected",
|
|
1794
1793
|
value: (function () {
|
|
1795
1794
|
var _setDiscountSelected = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee21(params) {
|
|
1796
|
-
var _tempOrder$holder, _this$store$order$get, _this$store$order$get2, list, beforeTarget, updated, updatedTarget, tempOrder, orderStore, discountModule, rulesModule, holders, nextDiscountList, _tempOrder$holder2, result, beforeSelectedIds, _iterator9, _step9, d, selectedResourceIds, _iterator10, _step10, _product$discount_lis, product, before,
|
|
1795
|
+
var _tempOrder$holder, _this$store$order$get, _this$store$order$get2, list, beforeTarget, updated, updatedTarget, tempOrder, orderStore, discountModule, rulesModule, holders, nextDiscountList, _tempOrder$holder2, result, beforeSelectedIds, _iterator9, _step9, d, selectedResourceIds, _iterator10, _step10, _product$discount_lis, product, before, totalPerUnitDiscount, newSellingPrice, afterApplyTarget, finalSummary, finalProduct, finalTarget;
|
|
1797
1796
|
return _regeneratorRuntime().wrap(function _callee21$(_context21) {
|
|
1798
1797
|
while (1) switch (_context21.prev = _context21.next) {
|
|
1799
1798
|
case 0:
|
|
@@ -1896,14 +1895,15 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
1896
1895
|
return rid != null && selectedResourceIds.has(rid);
|
|
1897
1896
|
});
|
|
1898
1897
|
if (product.discount_list.length < before) {
|
|
1899
|
-
|
|
1898
|
+
// 基于剩余的 discount_list 重算 selling_price。
|
|
1899
|
+
// 约定:pd.amount 为 per-unit 折扣额,remaining 加总即单品券后总折扣。
|
|
1900
|
+
totalPerUnitDiscount = product.discount_list.reduce(function (sum, pd) {
|
|
1900
1901
|
return sum + (pd.amount || 0);
|
|
1901
1902
|
}, 0);
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
product.payment_price = paymentStr;
|
|
1903
|
+
newSellingPrice = new Decimal(product.original_price || product.selling_price || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
|
|
1904
|
+
product.selling_price = newSellingPrice;
|
|
1905
1905
|
if (product.metadata) {
|
|
1906
|
-
product.metadata.main_product_selling_price =
|
|
1906
|
+
product.metadata.main_product_selling_price = newSellingPrice;
|
|
1907
1907
|
}
|
|
1908
1908
|
}
|
|
1909
1909
|
case 28:
|
|
@@ -2123,10 +2123,9 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
2123
2123
|
});
|
|
2124
2124
|
if (quotationPrice !== null) {
|
|
2125
2125
|
product.selling_price = quotationPrice;
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
product.payment_price = quotationPrice;
|
|
2126
|
+
product.original_price = quotationPrice;
|
|
2127
|
+
} else if (product.selling_price != null) {
|
|
2128
|
+
product.original_price = product.selling_price;
|
|
2130
2129
|
}
|
|
2131
2130
|
}
|
|
2132
2131
|
_context25.next = 7;
|
|
@@ -2619,7 +2618,7 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
2619
2618
|
key: "applyPrefillByItemRule",
|
|
2620
2619
|
value: function () {
|
|
2621
2620
|
var _applyPrefillByItemRule = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee36() {
|
|
2622
|
-
var strategyConfigs, businessData, prefillItems, productSourceMap, tempOrder, hasChanges, _iterator12, _step12, _prefillItem$product_, _targetProduct$_origi, prefillItem, productId, productVariantId, targetQuantity, sourceItem, productIndex, _sourceItem$price,
|
|
2621
|
+
var strategyConfigs, businessData, prefillItems, productSourceMap, tempOrder, hasChanges, _iterator12, _step12, _prefillItem$product_, _targetProduct$_origi, prefillItem, productId, productVariantId, targetQuantity, sourceItem, productIndex, _sourceItem$price, sellingPrice, targetProduct, existedQuantity, delta, nextProduct;
|
|
2623
2622
|
return _regeneratorRuntime().wrap(function _callee36$(_context36) {
|
|
2624
2623
|
while (1) switch (_context36.prev = _context36.next) {
|
|
2625
2624
|
case 0:
|
|
@@ -2669,7 +2668,7 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
2669
2668
|
_iterator12.s();
|
|
2670
2669
|
case 22:
|
|
2671
2670
|
if ((_step12 = _iterator12.n()).done) {
|
|
2672
|
-
_context36.next =
|
|
2671
|
+
_context36.next = 45;
|
|
2673
2672
|
break;
|
|
2674
2673
|
}
|
|
2675
2674
|
prefillItem = _step12.value;
|
|
@@ -2680,13 +2679,13 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
2680
2679
|
_context36.next = 29;
|
|
2681
2680
|
break;
|
|
2682
2681
|
}
|
|
2683
|
-
return _context36.abrupt("continue",
|
|
2682
|
+
return _context36.abrupt("continue", 43);
|
|
2684
2683
|
case 29:
|
|
2685
2684
|
if (!Number.isNaN(productVariantId)) {
|
|
2686
2685
|
_context36.next = 31;
|
|
2687
2686
|
break;
|
|
2688
2687
|
}
|
|
2689
|
-
return _context36.abrupt("continue",
|
|
2688
|
+
return _context36.abrupt("continue", 43);
|
|
2690
2689
|
case 31:
|
|
2691
2690
|
sourceItem = productSourceMap.get(buildProductKey(productId, productVariantId)) || productSourceMap.get(buildProductKey(productId, 0)) || null;
|
|
2692
2691
|
productIndex = getProductIdentityIndex(tempOrder.products, {
|
|
@@ -2694,19 +2693,16 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
2694
2693
|
product_variant_id: productVariantId
|
|
2695
2694
|
});
|
|
2696
2695
|
if (!(productIndex === -1)) {
|
|
2697
|
-
_context36.next =
|
|
2696
|
+
_context36.next = 38;
|
|
2698
2697
|
break;
|
|
2699
2698
|
}
|
|
2700
2699
|
sellingPrice = toPriceString((_sourceItem$price = sourceItem === null || sourceItem === void 0 ? void 0 : sourceItem.price) !== null && _sourceItem$price !== void 0 ? _sourceItem$price : sourceItem === null || sourceItem === void 0 ? void 0 : sourceItem.selling_price, '0.00');
|
|
2701
|
-
originalPrice = toPriceString((_ref5 = (_sourceItem$original_ = sourceItem === null || sourceItem === void 0 ? void 0 : sourceItem.original_price) !== null && _sourceItem$original_ !== void 0 ? _sourceItem$original_ : sourceItem === null || sourceItem === void 0 ? void 0 : sourceItem.price) !== null && _ref5 !== void 0 ? _ref5 : sellingPrice, sellingPrice);
|
|
2702
|
-
paymentPrice = toPriceString((_ref6 = (_sourceItem$payment_p = sourceItem === null || sourceItem === void 0 ? void 0 : sourceItem.payment_price) !== null && _sourceItem$payment_p !== void 0 ? _sourceItem$payment_p : sourceItem === null || sourceItem === void 0 ? void 0 : sourceItem.price) !== null && _ref6 !== void 0 ? _ref6 : sellingPrice, sellingPrice);
|
|
2703
2700
|
tempOrder.products.push(normalizeOrderProduct({
|
|
2704
2701
|
product_id: productId,
|
|
2705
2702
|
product_variant_id: productVariantId,
|
|
2706
2703
|
num: targetQuantity,
|
|
2707
2704
|
selling_price: sellingPrice,
|
|
2708
|
-
original_price:
|
|
2709
|
-
payment_price: paymentPrice,
|
|
2705
|
+
original_price: sellingPrice,
|
|
2710
2706
|
metadata: {
|
|
2711
2707
|
item_rule_prefill: true,
|
|
2712
2708
|
item_rule_id: prefillItem.ruleId
|
|
@@ -2717,8 +2713,8 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
2717
2713
|
})
|
|
2718
2714
|
}));
|
|
2719
2715
|
hasChanges = true;
|
|
2720
|
-
return _context36.abrupt("continue",
|
|
2721
|
-
case
|
|
2716
|
+
return _context36.abrupt("continue", 43);
|
|
2717
|
+
case 38:
|
|
2722
2718
|
targetProduct = tempOrder.products[productIndex];
|
|
2723
2719
|
existedQuantity = toNonNegativeInt(targetProduct.num);
|
|
2724
2720
|
delta = targetQuantity - existedQuantity;
|
|
@@ -2735,45 +2731,47 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
2735
2731
|
tempOrder.products[productIndex] = nextProduct;
|
|
2736
2732
|
hasChanges = true;
|
|
2737
2733
|
}
|
|
2738
|
-
case
|
|
2734
|
+
case 43:
|
|
2739
2735
|
_context36.next = 22;
|
|
2740
2736
|
break;
|
|
2741
|
-
case
|
|
2742
|
-
_context36.next =
|
|
2737
|
+
case 45:
|
|
2738
|
+
_context36.next = 50;
|
|
2743
2739
|
break;
|
|
2744
|
-
case
|
|
2745
|
-
_context36.prev =
|
|
2740
|
+
case 47:
|
|
2741
|
+
_context36.prev = 47;
|
|
2746
2742
|
_context36.t0 = _context36["catch"](20);
|
|
2747
2743
|
_iterator12.e(_context36.t0);
|
|
2748
|
-
case
|
|
2749
|
-
_context36.prev =
|
|
2744
|
+
case 50:
|
|
2745
|
+
_context36.prev = 50;
|
|
2750
2746
|
_iterator12.f();
|
|
2751
|
-
return _context36.finish(
|
|
2752
|
-
case
|
|
2747
|
+
return _context36.finish(50);
|
|
2748
|
+
case 53:
|
|
2753
2749
|
if (!hasChanges) {
|
|
2754
|
-
_context36.next =
|
|
2750
|
+
_context36.next = 58;
|
|
2755
2751
|
break;
|
|
2756
2752
|
}
|
|
2757
|
-
|
|
2753
|
+
// Prefill 属于 products CRUD 的一种形式:新增后让 Rules 重算,以支持自动应用可用优惠券。
|
|
2754
|
+
this.store.order.applyDiscount();
|
|
2755
|
+
_context36.next = 57;
|
|
2758
2756
|
return this.store.order.recalculateSummary({
|
|
2759
2757
|
createIfMissing: true
|
|
2760
2758
|
});
|
|
2761
|
-
case
|
|
2759
|
+
case 57:
|
|
2762
2760
|
this.store.order.persistTempOrder();
|
|
2763
|
-
case
|
|
2764
|
-
_context36.next =
|
|
2761
|
+
case 58:
|
|
2762
|
+
_context36.next = 60;
|
|
2765
2763
|
return this.refreshItemRuleQuantityLimits();
|
|
2766
|
-
case
|
|
2764
|
+
case 60:
|
|
2767
2765
|
this.itemRulePrefillApplied = true;
|
|
2768
2766
|
this.logMethodSuccess('applyPrefillByItemRule', {
|
|
2769
2767
|
prefillCount: prefillItems.length,
|
|
2770
2768
|
hasChanges: hasChanges
|
|
2771
2769
|
});
|
|
2772
|
-
case
|
|
2770
|
+
case 62:
|
|
2773
2771
|
case "end":
|
|
2774
2772
|
return _context36.stop();
|
|
2775
2773
|
}
|
|
2776
|
-
}, _callee36, this, [[20,
|
|
2774
|
+
}, _callee36, this, [[20, 47, 50, 53]]);
|
|
2777
2775
|
}));
|
|
2778
2776
|
function applyPrefillByItemRule() {
|
|
2779
2777
|
return _applyPrefillByItemRule.apply(this, arguments);
|
|
@@ -3078,14 +3076,14 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
3078
3076
|
key: "setOtherParams",
|
|
3079
3077
|
value: function () {
|
|
3080
3078
|
var _setOtherParams = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee43(params) {
|
|
3081
|
-
var
|
|
3082
|
-
|
|
3079
|
+
var _ref5,
|
|
3080
|
+
_ref5$cover,
|
|
3083
3081
|
cover,
|
|
3084
3082
|
_args43 = arguments;
|
|
3085
3083
|
return _regeneratorRuntime().wrap(function _callee43$(_context43) {
|
|
3086
3084
|
while (1) switch (_context43.prev = _context43.next) {
|
|
3087
3085
|
case 0:
|
|
3088
|
-
|
|
3086
|
+
_ref5 = _args43.length > 1 && _args43[1] !== undefined ? _args43[1] : {}, _ref5$cover = _ref5.cover, cover = _ref5$cover === void 0 ? false : _ref5$cover;
|
|
3089
3087
|
if (cover) {
|
|
3090
3088
|
this.otherParams = params;
|
|
3091
3089
|
} else {
|
|
@@ -250,7 +250,7 @@ var ItemRuleAdapter = class {
|
|
|
250
250
|
const config = action.config;
|
|
251
251
|
if (!config)
|
|
252
252
|
return null;
|
|
253
|
-
const { scope, quantityRules, targetType, targets } = config;
|
|
253
|
+
const { scope, quantityRules, targetType, targets, validationMessage } = config;
|
|
254
254
|
if (!this.shouldEvaluateForScope(scope, businessData.submissionIndex ?? 0)) {
|
|
255
255
|
return null;
|
|
256
256
|
}
|
|
@@ -289,6 +289,12 @@ var ItemRuleAdapter = class {
|
|
|
289
289
|
targets,
|
|
290
290
|
businessData
|
|
291
291
|
);
|
|
292
|
+
const formattedValidationMessage = this.formatValidationMessage(
|
|
293
|
+
validationMessage,
|
|
294
|
+
requiredMin,
|
|
295
|
+
requiredMax,
|
|
296
|
+
requiredExact
|
|
297
|
+
);
|
|
292
298
|
return {
|
|
293
299
|
ruleId: action.id,
|
|
294
300
|
targetType,
|
|
@@ -298,7 +304,9 @@ var ItemRuleAdapter = class {
|
|
|
298
304
|
remainingMax,
|
|
299
305
|
requiredExact,
|
|
300
306
|
mustInclude,
|
|
301
|
-
scope
|
|
307
|
+
scope,
|
|
308
|
+
validationMessage: formattedValidationMessage,
|
|
309
|
+
rawValidationMessage: validationMessage
|
|
302
310
|
};
|
|
303
311
|
}
|
|
304
312
|
/**
|
|
@@ -25,6 +25,21 @@ export declare const MAX_BUNS_PER_TABLE_STRATEGY: StrategyConfig;
|
|
|
25
25
|
* - Prefill Cart: 自动添加默认锅底 x 1
|
|
26
26
|
*/
|
|
27
27
|
export declare const HOTPOT_BASE_REQUIRED_STRATEGY: StrategyConfig;
|
|
28
|
+
/**
|
|
29
|
+
* 场景:4 款锅底里任选至少 1 款,不自动预填,不限制多选上限
|
|
30
|
+
*
|
|
31
|
+
* WHEN: Always active
|
|
32
|
+
* THEN:
|
|
33
|
+
* - Quantity Check: 4 个锅底商品合计数量 >= 1 (OR 组语义)
|
|
34
|
+
*
|
|
35
|
+
* 说明:
|
|
36
|
+
* - targets 里放多个 product_id 时,ItemRuleAdapter 会把它们视为 OR 组,
|
|
37
|
+
* 仅校验「合计数量」,不会要求每款各自满足 min。
|
|
38
|
+
* - ScanOrder 工具层 buildQuantityLimitIndex 会跳过多目标规则的
|
|
39
|
+
* 单品索引,避免 UI 把组级 min 误当作每张商品卡的减号下限,
|
|
40
|
+
* 锁死用户切换锅底的操作。
|
|
41
|
+
*/
|
|
42
|
+
export declare const HOTPOT_BASE_PICK_ONE_STRATEGY: StrategyConfig;
|
|
28
43
|
/**
|
|
29
44
|
* ItemRuleEvaluator 简洁调用示例
|
|
30
45
|
*
|
|
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
// src/model/strategy/adapter/itemRule/examples.ts
|
|
20
20
|
var examples_exports = {};
|
|
21
21
|
__export(examples_exports, {
|
|
22
|
+
HOTPOT_BASE_PICK_ONE_STRATEGY: () => HOTPOT_BASE_PICK_ONE_STRATEGY,
|
|
22
23
|
HOTPOT_BASE_REQUIRED_STRATEGY: () => HOTPOT_BASE_REQUIRED_STRATEGY,
|
|
23
24
|
MAX_BUNS_PER_TABLE_STRATEGY: () => MAX_BUNS_PER_TABLE_STRATEGY,
|
|
24
25
|
MIN_CONDIMENT_PER_PERSON_STRATEGY: () => MIN_CONDIMENT_PER_PERSON_STRATEGY,
|
|
@@ -190,6 +191,51 @@ var HOTPOT_BASE_REQUIRED_STRATEGY = {
|
|
|
190
191
|
}
|
|
191
192
|
]
|
|
192
193
|
};
|
|
194
|
+
var HOTPOT_BASE_PICK_ONE_STRATEGY = {
|
|
195
|
+
metadata: {
|
|
196
|
+
id: "RULE_HOTPOT_BASE_PICK_ONE",
|
|
197
|
+
name: {
|
|
198
|
+
"zh-CN": "锅底必选(四选一)",
|
|
199
|
+
en: "Hotpot base required (pick any)"
|
|
200
|
+
},
|
|
201
|
+
type: "item_rule",
|
|
202
|
+
description: {
|
|
203
|
+
"zh-CN": "4 款锅底任选至少 1 份",
|
|
204
|
+
en: "Pick at least 1 hotpot base from the available options"
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
conditions: {
|
|
208
|
+
operator: "and",
|
|
209
|
+
rules: [],
|
|
210
|
+
actionIds: ["quantity_check_hotpot_base_group"]
|
|
211
|
+
},
|
|
212
|
+
actions: [
|
|
213
|
+
{
|
|
214
|
+
id: "quantity_check_hotpot_base_group",
|
|
215
|
+
type: import_type.ITEM_RULE_ACTION_TYPES.QUANTITY_CHECK,
|
|
216
|
+
value: null,
|
|
217
|
+
target: "cart",
|
|
218
|
+
priority: 10,
|
|
219
|
+
config: {
|
|
220
|
+
targetType: "product",
|
|
221
|
+
targets: [
|
|
222
|
+
{ product_id: 30001 },
|
|
223
|
+
{ product_id: 30002 },
|
|
224
|
+
{ product_id: 30003 },
|
|
225
|
+
{ product_id: 30004 }
|
|
226
|
+
],
|
|
227
|
+
quantityRules: [
|
|
228
|
+
{ comparison: "minimum", source: "fixed", value: 1 }
|
|
229
|
+
],
|
|
230
|
+
scope: "first_submission_only",
|
|
231
|
+
validationMessage: {
|
|
232
|
+
"zh-CN": "请至少选择 {min} 款锅底",
|
|
233
|
+
en: "Please select at least {min} hotpot base"
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
]
|
|
238
|
+
};
|
|
193
239
|
function quickUseItemRuleEvaluator() {
|
|
194
240
|
const evaluator = new import_evaluator.ItemRuleEvaluator();
|
|
195
241
|
evaluator.setStrategyConfigs([
|
|
@@ -261,6 +307,7 @@ function runItemRuleEvaluatorDemo() {
|
|
|
261
307
|
}
|
|
262
308
|
// Annotate the CommonJS export names for ESM import in node:
|
|
263
309
|
0 && (module.exports = {
|
|
310
|
+
HOTPOT_BASE_PICK_ONE_STRATEGY,
|
|
264
311
|
HOTPOT_BASE_REQUIRED_STRATEGY,
|
|
265
312
|
MAX_BUNS_PER_TABLE_STRATEGY,
|
|
266
313
|
MIN_CONDIMENT_PER_PERSON_STRATEGY,
|