@pisell/pisellos 0.0.509 → 0.0.511
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/promotion/index.js +9 -0
- package/dist/modules/Order/index.d.ts +3 -6
- package/dist/modules/Order/index.js +114 -57
- package/dist/modules/Order/types.d.ts +12 -5
- package/dist/modules/Order/types.js +2 -0
- package/dist/modules/Order/utils.d.ts +1 -0
- package/dist/modules/Order/utils.js +33 -4
- package/dist/solution/ScanOrder/index.d.ts +7 -5
- package/dist/solution/ScanOrder/index.js +327 -274
- package/dist/solution/ScanOrder/types.d.ts +17 -0
- package/dist/solution/ScanOrder/types.js +13 -0
- package/dist/solution/ScanOrder/utils.d.ts +18 -3
- package/dist/solution/ScanOrder/utils.js +80 -13
- package/dist/solution/VenueBooking/index.d.ts +2 -5
- package/lib/model/strategy/adapter/promotion/index.js +49 -0
- package/lib/modules/Order/index.d.ts +3 -6
- package/lib/modules/Order/index.js +90 -26
- package/lib/modules/Order/types.d.ts +12 -5
- package/lib/modules/Order/utils.d.ts +1 -0
- package/lib/modules/Order/utils.js +28 -3
- package/lib/solution/ScanOrder/index.d.ts +7 -5
- package/lib/solution/ScanOrder/index.js +30 -0
- package/lib/solution/ScanOrder/types.d.ts +17 -0
- package/lib/solution/ScanOrder/utils.d.ts +18 -3
- package/lib/solution/ScanOrder/utils.js +58 -5
- package/lib/solution/VenueBooking/index.d.ts +2 -5
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// 导出评估器
|
|
2
|
+
export { PromotionEvaluator } from "./evaluator";
|
|
3
|
+
|
|
4
|
+
// 导出适配器
|
|
5
|
+
export { PromotionAdapter } from "./adapter";
|
|
6
|
+
export { default } from "./adapter";
|
|
7
|
+
|
|
8
|
+
// 导出策略配置示例常量
|
|
9
|
+
export { X_ITEMS_FOR_Y_PRICE_STRATEGY, BUY_X_GET_Y_FREE_STRATEGY } from "./examples";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Module, PisellCore, ModuleOptions } from '../../types';
|
|
2
2
|
import { BaseModule } from '../BaseModule';
|
|
3
|
-
import { OrderModuleAPI, CommitOrderParams, SubmitScanOrderParams, ScanOrderMoreParams, CheckoutOrderParams } from './types';
|
|
3
|
+
import { OrderModuleAPI, CommitOrderParams, SubmitScanOrderParams, ScanOrderMoreParams, CheckoutOrderParams, UpdateProductInOrderParams } from './types';
|
|
4
4
|
import { CartItem } from '../Cart/types';
|
|
5
5
|
import { type SubmitPayloadEnhancer } from './utils';
|
|
6
6
|
import type { ScanOrderOrderProduct, ScanOrderOrderProductIdentity, ScanOrderSummary, ScanOrderTempOrder } from '../../solution/ScanOrder/types';
|
|
@@ -71,11 +71,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
71
71
|
updateTempOrderBuzzer(buzzer: string): string;
|
|
72
72
|
updateTempOrderContactsInfo(contactsInfo: any[]): any[];
|
|
73
73
|
addProductToOrder(product: Partial<ScanOrderOrderProduct> & ScanOrderOrderProductIdentity): Promise<ScanOrderOrderProduct[]>;
|
|
74
|
-
updateProductInOrder(params:
|
|
75
|
-
product_id: number | null;
|
|
76
|
-
product_variant_id: number;
|
|
77
|
-
updates: Partial<ScanOrderOrderProduct>;
|
|
78
|
-
}): Promise<ScanOrderOrderProduct[]>;
|
|
74
|
+
updateProductInOrder(params: UpdateProductInOrderParams): Promise<ScanOrderOrderProduct[]>;
|
|
79
75
|
removeProductFromOrder(identity: ScanOrderOrderProductIdentity): Promise<ScanOrderOrderProduct[]>;
|
|
80
76
|
submitTempOrder<T = any>(params?: {
|
|
81
77
|
cacheId?: string;
|
|
@@ -119,3 +115,4 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
119
115
|
getOrderInfoByRemote(order_id: number): Promise<any>;
|
|
120
116
|
getLastOrderInfo(): Record<string, any> | undefined;
|
|
121
117
|
}
|
|
118
|
+
export type { UpdateProductInOrderParams } from './types';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
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); }
|
|
2
|
-
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; } } }; }
|
|
3
1
|
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
4
2
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
5
|
-
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
6
3
|
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
7
4
|
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
5
|
+
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); }
|
|
6
|
+
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; } } }; }
|
|
7
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
8
8
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
9
9
|
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; }
|
|
10
10
|
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; }
|
|
@@ -25,10 +25,10 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
|
|
|
25
25
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
26
26
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
27
27
|
import { BaseModule } from "../BaseModule";
|
|
28
|
-
import { generateDuration, getAllDiscountList, mergeRelationForms, buildSubmitPayload, createDefaultTempOrder, createDefaultOrderRulesHooks, createEmptySummary, formatDateTime, filterProductsForScanOrderMore, formatV1Product, isTempOrder } from "./utils";
|
|
28
|
+
import { generateDuration, getAllDiscountList, mergeRelationForms, buildSubmitPayload, createDefaultTempOrder, createDefaultOrderRulesHooks, createEmptySummary, createUuidV4, formatDateTime, filterProductsForScanOrderMore, formatV1Product, isTempOrder } from "./utils";
|
|
29
29
|
import { isNormalProduct } from "../Product/utils";
|
|
30
30
|
import dayjs from 'dayjs';
|
|
31
|
-
import { getProductIdentityIndex, getSafeProductNum, isIdentityMatch, normalizeOrderProduct } from "../../solution/ScanOrder/utils";
|
|
31
|
+
import { buildProductLineFingerprint, getProductIdentityIndex, getSafeProductNum, isIdentityMatch, normalizeOrderProduct } from "../../solution/ScanOrder/utils";
|
|
32
32
|
import { DiscountModule } from "../Discount";
|
|
33
33
|
import { RulesModule } from "../Rules";
|
|
34
34
|
import { UnavailableReason } from "../Rules/types";
|
|
@@ -387,6 +387,40 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
387
387
|
this.window.localStorage.removeItem(key);
|
|
388
388
|
return;
|
|
389
389
|
}
|
|
390
|
+
if (Array.isArray(parsedData.products)) {
|
|
391
|
+
var _iterator = _createForOfIteratorHelper(parsedData.products),
|
|
392
|
+
_step;
|
|
393
|
+
try {
|
|
394
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
395
|
+
var p = _step.value;
|
|
396
|
+
if (!p || _typeof(p) !== 'object') continue;
|
|
397
|
+
if (!Array.isArray(p.product_option_item)) {
|
|
398
|
+
p.product_option_item = [];
|
|
399
|
+
}
|
|
400
|
+
if (!Array.isArray(p.product_bundle)) {
|
|
401
|
+
p.product_bundle = [];
|
|
402
|
+
}
|
|
403
|
+
// 不透明 identity 契约:旧缓存里可能没有 identity_key,
|
|
404
|
+
// 此处统一回填 UUID 并同步 metadata.unique_identification_number,
|
|
405
|
+
// 避免升级后 UI 侧持有的 rowKey 找不到对应行。
|
|
406
|
+
var row = p;
|
|
407
|
+
if (typeof row.identity_key !== 'string' || row.identity_key.length === 0) {
|
|
408
|
+
var newKey = createUuidV4();
|
|
409
|
+
row.identity_key = newKey;
|
|
410
|
+
if (!row.metadata || _typeof(row.metadata) !== 'object') {
|
|
411
|
+
row.metadata = {};
|
|
412
|
+
}
|
|
413
|
+
if (!row.metadata.unique_identification_number) {
|
|
414
|
+
row.metadata.unique_identification_number = newKey;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
} catch (err) {
|
|
419
|
+
_iterator.e(err);
|
|
420
|
+
} finally {
|
|
421
|
+
_iterator.f();
|
|
422
|
+
}
|
|
423
|
+
}
|
|
390
424
|
this.store.tempOrder = parsedData;
|
|
391
425
|
} catch (_unused2) {
|
|
392
426
|
var _this$window;
|
|
@@ -591,31 +625,59 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
591
625
|
key: "addProductToOrder",
|
|
592
626
|
value: function () {
|
|
593
627
|
var _addProductToOrder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(product) {
|
|
594
|
-
var tempOrder, normalizedProduct, productIndex, targetProduct;
|
|
628
|
+
var tempOrder, hasExplicitIdentityKey, normalizedProduct, productIndex, targetProduct, incomingFingerprint, matchedIndex, _normalizedProduct, _targetProduct, _normalizedProduct2;
|
|
595
629
|
return _regeneratorRuntime().wrap(function _callee7$(_context7) {
|
|
596
630
|
while (1) switch (_context7.prev = _context7.next) {
|
|
597
631
|
case 0:
|
|
598
632
|
tempOrder = this.ensureTempOrder();
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
633
|
+
hasExplicitIdentityKey = typeof product.identity_key === 'string' && product.identity_key.length > 0;
|
|
634
|
+
if (hasExplicitIdentityKey) {
|
|
635
|
+
// 调用方自持 identity_key(如 VenueBooking 外部生成)→ 走严格 identity 合并。
|
|
636
|
+
normalizedProduct = normalizeOrderProduct(product);
|
|
637
|
+
productIndex = getProductIdentityIndex(tempOrder.products, normalizedProduct);
|
|
638
|
+
if (productIndex === -1) {
|
|
639
|
+
tempOrder.products.push(normalizedProduct);
|
|
640
|
+
} else {
|
|
641
|
+
targetProduct = tempOrder.products[productIndex];
|
|
642
|
+
tempOrder.products[productIndex] = _objectSpread(_objectSpread(_objectSpread({}, targetProduct), normalizedProduct), {}, {
|
|
643
|
+
num: getSafeProductNum(targetProduct.num + normalizedProduct.num),
|
|
644
|
+
_origin: normalizedProduct._origin || targetProduct._origin
|
|
645
|
+
});
|
|
646
|
+
}
|
|
603
647
|
} else {
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
648
|
+
// 无 identity_key:按 SKU + 内容指纹(options + bundle)匹配既有行以累加数量;
|
|
649
|
+
// 命中时保留已有 identity_key,未命中才由 normalizeOrderProduct 自动生成 UUID。
|
|
650
|
+
incomingFingerprint = buildProductLineFingerprint(product.product_option_item, product.product_bundle);
|
|
651
|
+
matchedIndex = tempOrder.products.findIndex(function (item) {
|
|
652
|
+
if (item.product_id !== product.product_id) return false;
|
|
653
|
+
if (item.product_variant_id !== product.product_variant_id) return false;
|
|
654
|
+
var existedFingerprint = buildProductLineFingerprint(item.product_option_item, item.product_bundle);
|
|
655
|
+
return existedFingerprint === incomingFingerprint;
|
|
608
656
|
});
|
|
657
|
+
if (matchedIndex === -1) {
|
|
658
|
+
_normalizedProduct = normalizeOrderProduct(product);
|
|
659
|
+
tempOrder.products.push(_normalizedProduct);
|
|
660
|
+
} else {
|
|
661
|
+
_targetProduct = tempOrder.products[matchedIndex];
|
|
662
|
+
_normalizedProduct2 = normalizeOrderProduct(_objectSpread(_objectSpread({}, product), {}, {
|
|
663
|
+
identity_key: _targetProduct.identity_key
|
|
664
|
+
}));
|
|
665
|
+
tempOrder.products[matchedIndex] = _objectSpread(_objectSpread(_objectSpread({}, _targetProduct), _normalizedProduct2), {}, {
|
|
666
|
+
identity_key: _targetProduct.identity_key,
|
|
667
|
+
num: getSafeProductNum(_targetProduct.num + _normalizedProduct2.num),
|
|
668
|
+
_origin: _normalizedProduct2._origin || _targetProduct._origin
|
|
669
|
+
});
|
|
670
|
+
}
|
|
609
671
|
}
|
|
610
672
|
this.applyDiscount();
|
|
611
|
-
_context7.next =
|
|
673
|
+
_context7.next = 6;
|
|
612
674
|
return this.recalculateSummary({
|
|
613
675
|
createIfMissing: true
|
|
614
676
|
});
|
|
615
|
-
case
|
|
677
|
+
case 6:
|
|
616
678
|
this.persistTempOrder();
|
|
617
679
|
return _context7.abrupt("return", tempOrder.products);
|
|
618
|
-
case
|
|
680
|
+
case 8:
|
|
619
681
|
case "end":
|
|
620
682
|
return _context7.stop();
|
|
621
683
|
}
|
|
@@ -630,22 +692,26 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
630
692
|
key: "updateProductInOrder",
|
|
631
693
|
value: function () {
|
|
632
694
|
var _updateProductInOrder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(params) {
|
|
633
|
-
var product_id, product_variant_id, updates, tempOrder, productIndex, targetProduct, nextProduct;
|
|
695
|
+
var product_id, product_variant_id, updates, identity_key, product_option_item, product_bundle, tempOrder, identityLookup, productIndex, targetProduct, nextProduct;
|
|
634
696
|
return _regeneratorRuntime().wrap(function _callee8$(_context8) {
|
|
635
697
|
while (1) switch (_context8.prev = _context8.next) {
|
|
636
698
|
case 0:
|
|
637
|
-
product_id = params.product_id, product_variant_id = params.product_variant_id, updates = params.updates;
|
|
699
|
+
product_id = params.product_id, product_variant_id = params.product_variant_id, updates = params.updates, identity_key = params.identity_key, product_option_item = params.product_option_item, product_bundle = params.product_bundle;
|
|
638
700
|
tempOrder = this.ensureTempOrder();
|
|
639
|
-
|
|
701
|
+
identityLookup = {
|
|
640
702
|
product_id: product_id,
|
|
641
703
|
product_variant_id: product_variant_id
|
|
642
|
-
}
|
|
704
|
+
};
|
|
705
|
+
if (identity_key !== undefined) identityLookup.identity_key = identity_key;
|
|
706
|
+
if (product_option_item !== undefined) identityLookup.product_option_item = product_option_item;
|
|
707
|
+
if (product_bundle !== undefined) identityLookup.product_bundle = product_bundle;
|
|
708
|
+
productIndex = getProductIdentityIndex(tempOrder.products, identityLookup);
|
|
643
709
|
if (!(productIndex === -1)) {
|
|
644
|
-
_context8.next =
|
|
710
|
+
_context8.next = 9;
|
|
645
711
|
break;
|
|
646
712
|
}
|
|
647
713
|
throw new Error('[Order] 目标商品不存在,无法更新');
|
|
648
|
-
case
|
|
714
|
+
case 9:
|
|
649
715
|
targetProduct = tempOrder.products[productIndex];
|
|
650
716
|
nextProduct = _objectSpread(_objectSpread(_objectSpread({}, targetProduct), updates), {}, {
|
|
651
717
|
product_id: product_id,
|
|
@@ -654,14 +720,14 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
654
720
|
nextProduct.num = getSafeProductNum(nextProduct.num);
|
|
655
721
|
tempOrder.products[productIndex] = nextProduct;
|
|
656
722
|
this.applyDiscount();
|
|
657
|
-
_context8.next =
|
|
723
|
+
_context8.next = 16;
|
|
658
724
|
return this.recalculateSummary({
|
|
659
725
|
createIfMissing: true
|
|
660
726
|
});
|
|
661
|
-
case
|
|
727
|
+
case 16:
|
|
662
728
|
this.persistTempOrder();
|
|
663
729
|
return _context8.abrupt("return", tempOrder.products);
|
|
664
|
-
case
|
|
730
|
+
case 18:
|
|
665
731
|
case "end":
|
|
666
732
|
return _context8.stop();
|
|
667
733
|
}
|
|
@@ -676,32 +742,23 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
676
742
|
key: "removeProductFromOrder",
|
|
677
743
|
value: function () {
|
|
678
744
|
var _removeProductFromOrder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(identity) {
|
|
679
|
-
var tempOrder
|
|
745
|
+
var tempOrder;
|
|
680
746
|
return _regeneratorRuntime().wrap(function _callee9$(_context9) {
|
|
681
747
|
while (1) switch (_context9.prev = _context9.next) {
|
|
682
748
|
case 0:
|
|
683
749
|
tempOrder = this.ensureTempOrder();
|
|
684
|
-
beforeProducts = tempOrder.products;
|
|
685
750
|
tempOrder.products = tempOrder.products.filter(function (item) {
|
|
686
751
|
return !isIdentityMatch(item, identity);
|
|
687
752
|
});
|
|
688
|
-
removedByStrictIdentity = beforeProducts.length - tempOrder.products.length;
|
|
689
|
-
if (removedByStrictIdentity === 0 && identity.identity_key) {
|
|
690
|
-
tempOrder.products = tempOrder.products.filter(function (item) {
|
|
691
|
-
var isSameProduct = String(item.product_id) === String(identity.product_id) && String(item.product_variant_id) === String(identity.product_variant_id);
|
|
692
|
-
var hasNoIdentityKey = !item.identity_key;
|
|
693
|
-
return !(isSameProduct && hasNoIdentityKey);
|
|
694
|
-
});
|
|
695
|
-
}
|
|
696
753
|
this.applyDiscount();
|
|
697
|
-
_context9.next =
|
|
754
|
+
_context9.next = 5;
|
|
698
755
|
return this.recalculateSummary({
|
|
699
756
|
createIfMissing: true
|
|
700
757
|
});
|
|
701
|
-
case
|
|
758
|
+
case 5:
|
|
702
759
|
this.persistTempOrder();
|
|
703
760
|
return _context9.abrupt("return", tempOrder.products);
|
|
704
|
-
case
|
|
761
|
+
case 7:
|
|
705
762
|
case "end":
|
|
706
763
|
return _context9.stop();
|
|
707
764
|
}
|
|
@@ -1135,46 +1192,46 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1135
1192
|
*/
|
|
1136
1193
|
function populateSavedAmounts(productList, discountList) {
|
|
1137
1194
|
var savedMap = new Map();
|
|
1138
|
-
var
|
|
1139
|
-
|
|
1195
|
+
var _iterator2 = _createForOfIteratorHelper(productList),
|
|
1196
|
+
_step2;
|
|
1140
1197
|
try {
|
|
1141
|
-
for (
|
|
1142
|
-
var product =
|
|
1198
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
1199
|
+
var product = _step2.value;
|
|
1143
1200
|
var qty = product.num || 1;
|
|
1144
|
-
var
|
|
1145
|
-
|
|
1201
|
+
var _iterator4 = _createForOfIteratorHelper(product.discount_list || []),
|
|
1202
|
+
_step4;
|
|
1146
1203
|
try {
|
|
1147
|
-
for (
|
|
1204
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
1148
1205
|
var _pd$discount, _pd$metadata;
|
|
1149
|
-
var pd =
|
|
1206
|
+
var pd = _step4.value;
|
|
1150
1207
|
var discountKey = ((_pd$discount = pd.discount) === null || _pd$discount === void 0 ? void 0 : _pd$discount.resource_id) || pd.id;
|
|
1151
1208
|
if (discountKey == null) continue;
|
|
1152
1209
|
var amount = new Decimal(pd.amount || 0).times(qty).plus(((_pd$metadata = pd.metadata) === null || _pd$metadata === void 0 ? void 0 : _pd$metadata.product_discount_difference) || 0);
|
|
1153
1210
|
savedMap.set(discountKey, (savedMap.get(discountKey) || new Decimal(0)).plus(amount));
|
|
1154
1211
|
}
|
|
1155
1212
|
} catch (err) {
|
|
1156
|
-
|
|
1213
|
+
_iterator4.e(err);
|
|
1157
1214
|
} finally {
|
|
1158
|
-
|
|
1215
|
+
_iterator4.f();
|
|
1159
1216
|
}
|
|
1160
1217
|
}
|
|
1161
1218
|
} catch (err) {
|
|
1162
|
-
|
|
1219
|
+
_iterator2.e(err);
|
|
1163
1220
|
} finally {
|
|
1164
|
-
|
|
1221
|
+
_iterator2.f();
|
|
1165
1222
|
}
|
|
1166
|
-
var
|
|
1167
|
-
|
|
1223
|
+
var _iterator3 = _createForOfIteratorHelper(discountList),
|
|
1224
|
+
_step3;
|
|
1168
1225
|
try {
|
|
1169
|
-
for (
|
|
1170
|
-
var d =
|
|
1226
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
1227
|
+
var d = _step3.value;
|
|
1171
1228
|
var key = d.id;
|
|
1172
1229
|
d.savedAmount = d.isSelected && key != null && savedMap.has(key) ? savedMap.get(key).toNumber() : 0;
|
|
1173
1230
|
}
|
|
1174
1231
|
} catch (err) {
|
|
1175
|
-
|
|
1232
|
+
_iterator3.e(err);
|
|
1176
1233
|
} finally {
|
|
1177
|
-
|
|
1234
|
+
_iterator3.f();
|
|
1178
1235
|
}
|
|
1179
1236
|
}
|
|
1180
1237
|
}]);
|
|
@@ -16,6 +16,15 @@ export interface OrderState {
|
|
|
16
16
|
discount: DiscountModule | null;
|
|
17
17
|
rules: RulesModule | null;
|
|
18
18
|
}
|
|
19
|
+
/** 更新购物车行:仅传 SKU 时命中同 SKU 第一行;多行同 SKU 须传 identity_key / 选项指纹等 */
|
|
20
|
+
export interface UpdateProductInOrderParams {
|
|
21
|
+
product_id: number | null;
|
|
22
|
+
product_variant_id: number;
|
|
23
|
+
updates: Partial<ScanOrderOrderProduct>;
|
|
24
|
+
identity_key?: string;
|
|
25
|
+
product_option_item?: any[];
|
|
26
|
+
product_bundle?: any[];
|
|
27
|
+
}
|
|
19
28
|
/**
|
|
20
29
|
* 订单信息
|
|
21
30
|
*/
|
|
@@ -43,6 +52,8 @@ export interface SubmitScanOrderProduct {
|
|
|
43
52
|
discount_list: any[];
|
|
44
53
|
product_bundle: any[];
|
|
45
54
|
metadata: Record<string, any>;
|
|
55
|
+
/** 商品行备注 */
|
|
56
|
+
note?: string;
|
|
46
57
|
}
|
|
47
58
|
export interface SubmitScanOrderSummary {
|
|
48
59
|
product_quantity: number;
|
|
@@ -210,11 +221,7 @@ export interface OrderModuleAPI {
|
|
|
210
221
|
updateTempOrderBuzzer: (buzzer: string) => string;
|
|
211
222
|
updateTempOrderContactsInfo: (contactsInfo: any[]) => any[];
|
|
212
223
|
addProductToOrder: (product: Partial<ScanOrderOrderProduct> & ScanOrderOrderProductIdentity) => Promise<ScanOrderOrderProduct[]>;
|
|
213
|
-
updateProductInOrder: (params:
|
|
214
|
-
product_id: number | null;
|
|
215
|
-
product_variant_id: number;
|
|
216
|
-
updates: Partial<ScanOrderOrderProduct>;
|
|
217
|
-
}) => Promise<ScanOrderOrderProduct[]>;
|
|
224
|
+
updateProductInOrder: (params: UpdateProductInOrderParams) => Promise<ScanOrderOrderProduct[]>;
|
|
218
225
|
removeProductFromOrder: (identity: ScanOrderOrderProductIdentity) => Promise<ScanOrderOrderProduct[]>;
|
|
219
226
|
persistTempOrder: () => void;
|
|
220
227
|
submitTempOrder: <T = any>(params?: {
|
|
@@ -18,7 +18,7 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
|
|
|
18
18
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
19
19
|
import dayjs from "dayjs";
|
|
20
20
|
import Decimal from 'decimal.js';
|
|
21
|
-
import { createEmptySummary } from "../../solution/ScanOrder/utils";
|
|
21
|
+
import { buildProductLineFingerprint, createEmptySummary } from "../../solution/ScanOrder/utils";
|
|
22
22
|
/**
|
|
23
23
|
* OrderModule 默认 Rules 钩子工厂。
|
|
24
24
|
*
|
|
@@ -47,7 +47,11 @@ export function createDefaultOrderRulesHooks() {
|
|
|
47
47
|
var _product$_origin, _product$_origin2, _product$_origin3, _product$_origin4;
|
|
48
48
|
return {
|
|
49
49
|
id: product.product_id,
|
|
50
|
-
|
|
50
|
+
// Rules 引擎用 _id 作为 processedProductsMap 键;必须与购物车行级 identity 一致,
|
|
51
|
+
// 否则同 SKU 不同小料会在 calcDiscount 重组时互相覆盖。
|
|
52
|
+
// 不透明 identity 契约下,normalizeOrderProduct / restoreTempOrderFromStorage 已保证 identity_key 必存在;
|
|
53
|
+
// 留 fingerprint 分支仅作 Rules 单测里直接传裸 product 时的兜底。
|
|
54
|
+
_id: product.identity_key ? "".concat(product.product_id, "_").concat(product.product_variant_id, "_").concat(product.identity_key) : "".concat(product.product_id, "_").concat(product.product_variant_id, "_").concat(buildProductLineFingerprint(product.product_option_item, product.product_bundle)),
|
|
51
55
|
price: product.selling_price,
|
|
52
56
|
total: new Decimal(product.selling_price || 0).times(product.num || 1).toNumber(),
|
|
53
57
|
origin_total: new Decimal(product.original_price || product.selling_price || 0).times(product.num || 1).toNumber(),
|
|
@@ -168,6 +172,29 @@ export function formatDateTime(date) {
|
|
|
168
172
|
function normalizeSubmitPlatform(platform) {
|
|
169
173
|
return (platform === null || platform === void 0 ? void 0 : platform.toLowerCase()) === 'pc' ? 'PC' : 'H5';
|
|
170
174
|
}
|
|
175
|
+
|
|
176
|
+
// 出站重命名:后端 checkout 协议字段 option_group_item_id;
|
|
177
|
+
// tempOrder / UI 运行时一律使用 product_option_item_id。仅保留后端契约字段,
|
|
178
|
+
// 与 src/modules/Cart/utils/cartProduct.ts#formatOptionsToOrigin 形状一致。
|
|
179
|
+
function formatSubmitOptionItems(options) {
|
|
180
|
+
if (!Array.isArray(options)) return [];
|
|
181
|
+
return options.map(function (d) {
|
|
182
|
+
var _d$option_group_item_;
|
|
183
|
+
return {
|
|
184
|
+
num: d === null || d === void 0 ? void 0 : d.num,
|
|
185
|
+
option_group_item_id: (_d$option_group_item_ = d === null || d === void 0 ? void 0 : d.option_group_item_id) !== null && _d$option_group_item_ !== void 0 ? _d$option_group_item_ : d === null || d === void 0 ? void 0 : d.product_option_item_id,
|
|
186
|
+
option_group_id: d === null || d === void 0 ? void 0 : d.option_group_id
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function formatSubmitBundleItems(bundle) {
|
|
191
|
+
if (!Array.isArray(bundle)) return [];
|
|
192
|
+
return bundle.map(function (b) {
|
|
193
|
+
return _objectSpread(_objectSpread({}, b), {}, {
|
|
194
|
+
option: formatSubmitOptionItems(b === null || b === void 0 ? void 0 : b.option)
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
}
|
|
171
198
|
function normalizeSubmitProduct(product) {
|
|
172
199
|
var _origin = product._origin,
|
|
173
200
|
identity_key = product.identity_key,
|
|
@@ -194,9 +221,9 @@ function normalizeSubmitProduct(product) {
|
|
|
194
221
|
return _objectSpread(_objectSpread(_objectSpread({}, submitProduct), bookingUid ? {
|
|
195
222
|
booking_uid: bookingUid
|
|
196
223
|
} : {}), {}, {
|
|
197
|
-
product_option_item: submitProduct.product_option_item
|
|
224
|
+
product_option_item: formatSubmitOptionItems(submitProduct.product_option_item),
|
|
198
225
|
discount_list: submitProduct.discount_list || [],
|
|
199
|
-
product_bundle: submitProduct.product_bundle
|
|
226
|
+
product_bundle: formatSubmitBundleItems(submitProduct.product_bundle),
|
|
200
227
|
metadata: cleanMetadata,
|
|
201
228
|
// 出站兼容:后端仍消费 payment_price 字段,从 selling_price(券后单价)派生。
|
|
202
229
|
payment_price: submitProduct.selling_price
|
|
@@ -400,6 +427,7 @@ export function filterProductsForScanOrderMore(products) {
|
|
|
400
427
|
}
|
|
401
428
|
export function formatV1Product(products) {
|
|
402
429
|
return products.map(function (product) {
|
|
430
|
+
var _product$note;
|
|
403
431
|
return {
|
|
404
432
|
bundle: product.product_bundle,
|
|
405
433
|
key: product.product_id,
|
|
@@ -407,6 +435,7 @@ export function formatV1Product(products) {
|
|
|
407
435
|
product_id: product.product_id,
|
|
408
436
|
product_variant_id: product.product_variant_id,
|
|
409
437
|
num: product.num,
|
|
438
|
+
note: String((_product$note = product.note) !== null && _product$note !== void 0 ? _product$note : ''),
|
|
410
439
|
rowKey: product.product_id,
|
|
411
440
|
session: null,
|
|
412
441
|
unique: createUuidV4()
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Module, ModuleOptions, PisellCore } from '../../types';
|
|
2
2
|
import { BaseModule } from '../../modules/BaseModule';
|
|
3
3
|
import { ScanOrderAddLogParams, ScanOrderAvailabilityInfo, ScanOrderOrderProduct, ScanOrderOrderProductIdentity, ScanOrderScanCodeResult } from './types';
|
|
4
|
+
import type { UpdateProductInOrderParams } from '../../modules/Order/types';
|
|
4
5
|
import type { Discount } from '../../modules/Discount/types';
|
|
5
6
|
import { type CartItemSummary, type PaxInfo, type QuantityCheckResult, type QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
|
|
6
7
|
import type { StrategyConfig } from '../../model/strategy/type';
|
|
@@ -85,11 +86,12 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
|
|
|
85
86
|
private buildSubmitPayloadEnhancer;
|
|
86
87
|
submitScanOrder<T = any>(): Promise<T>;
|
|
87
88
|
addProductToOrder(product: Partial<ScanOrderOrderProduct> & ScanOrderOrderProductIdentity): Promise<ScanOrderOrderProduct[]>;
|
|
88
|
-
updateProductInOrder(params:
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
updateProductInOrder(params: UpdateProductInOrderParams): Promise<ScanOrderOrderProduct[]>;
|
|
90
|
+
/**
|
|
91
|
+
* 设置单行商品备注(与整单 `updateTempOrderNote` 区分)。
|
|
92
|
+
* 多行同 SKU 时必须传入与删除/更新一致的 identity(如 `identity_key`)。
|
|
93
|
+
*/
|
|
94
|
+
setOrderProductLineNote(identity: ScanOrderOrderProductIdentity, note: string): Promise<ScanOrderOrderProduct[]>;
|
|
93
95
|
removeProductFromOrder(identity: ScanOrderOrderProductIdentity): Promise<ScanOrderOrderProduct[]>;
|
|
94
96
|
private loadRuntimeConfigs;
|
|
95
97
|
private syncItemRuleConfigsFromDineInConfig;
|