@pisell/pisellos 2.3.101 → 2.3.103
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/dataVariant/evaluator.d.ts +18 -2
- package/dist/model/strategy/adapter/dataVariant/evaluator.js +287 -101
- package/dist/model/strategy/adapter/dataVariant/type.d.ts +25 -0
- package/dist/model/strategy/adapter/promotion/index.js +9 -0
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +10 -7
- package/dist/modules/Discount/index.d.ts +2 -0
- package/dist/modules/Discount/index.js +38 -5
- package/dist/modules/Discount/types.d.ts +11 -0
- package/dist/modules/Order/index.d.ts +29 -3
- package/dist/modules/Order/index.js +1105 -703
- package/dist/modules/Order/types.d.ts +14 -6
- package/dist/modules/Order/types.js +1 -1
- package/dist/modules/Order/utils/virtualSettlement.d.ts +63 -0
- package/dist/modules/Order/utils/virtualSettlement.js +284 -0
- package/dist/modules/Order/utils.d.ts +1 -0
- package/dist/modules/Order/utils.js +63 -24
- package/dist/modules/Product/types.d.ts +23 -0
- package/dist/modules/SalesSummary/index.d.ts +1 -0
- package/dist/modules/SalesSummary/index.js +4 -3
- package/dist/modules/SalesSummary/types.d.ts +1 -0
- package/dist/modules/SalesSummary/utils.d.ts +1 -0
- package/dist/modules/SalesSummary/utils.js +21 -1
- package/dist/solution/BaseSales/index.d.ts +10 -1
- package/dist/solution/BaseSales/index.js +1074 -746
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +72 -9
- package/dist/solution/BookingByStep/index.d.ts +2 -2
- package/dist/solution/BookingTicket/utils/addProductDecision.js +2 -1
- package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +18 -2
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +137 -6
- package/lib/model/strategy/adapter/dataVariant/type.d.ts +25 -0
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +4 -0
- package/lib/modules/Discount/index.d.ts +2 -0
- package/lib/modules/Discount/index.js +31 -2
- package/lib/modules/Discount/types.d.ts +11 -0
- package/lib/modules/Order/index.d.ts +29 -3
- package/lib/modules/Order/index.js +326 -51
- package/lib/modules/Order/types.d.ts +14 -6
- package/lib/modules/Order/types.js +1 -1
- package/lib/modules/Order/utils/virtualSettlement.d.ts +63 -0
- package/lib/modules/Order/utils/virtualSettlement.js +262 -0
- package/lib/modules/Order/utils.d.ts +1 -0
- package/lib/modules/Order/utils.js +57 -20
- package/lib/modules/Product/types.d.ts +23 -0
- package/lib/modules/SalesSummary/index.d.ts +1 -0
- package/lib/modules/SalesSummary/index.js +4 -2
- package/lib/modules/SalesSummary/types.d.ts +1 -0
- package/lib/modules/SalesSummary/utils.d.ts +1 -0
- package/lib/modules/SalesSummary/utils.js +17 -1
- package/lib/solution/BaseSales/index.d.ts +10 -1
- package/lib/solution/BaseSales/index.js +228 -20
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +38 -0
- package/lib/solution/BookingByStep/index.d.ts +2 -2
- package/lib/solution/BookingTicket/utils/addProductDecision.js +1 -0
- package/package.json +1 -1
|
@@ -4,6 +4,13 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
4
4
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
5
5
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
6
6
|
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); }
|
|
7
|
+
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; } } }; }
|
|
8
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
9
|
+
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."); }
|
|
10
|
+
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); }
|
|
11
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
12
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
13
|
+
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; }
|
|
7
14
|
import { composeLinePrice, getBundleSellingMagnitude, normalizeProductSkuOptions, sumOptionUnitPrice } from "../../../modules/Order/utils";
|
|
8
15
|
import { buildManualProductDiscountItem, mergeManualProductDiscountIntoList, resolveManualDiscountOriginTotal, resolveManualDiscountReasonFromSources, shouldBuildManualProductDiscount } from "../../../modules/Order/utils/manualProductDiscount";
|
|
9
16
|
function toNumber(value) {
|
|
@@ -45,6 +52,54 @@ function firstNonBlank() {
|
|
|
45
52
|
return !isBlankValue(value);
|
|
46
53
|
});
|
|
47
54
|
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 取第一份接口权威 Data Variant 命中结果并复制数组。
|
|
58
|
+
* 空数组表示规则已计算但无命中,必须与字段缺失区分。
|
|
59
|
+
*/
|
|
60
|
+
function cloneFirstDataVariantIds() {
|
|
61
|
+
for (var _len2 = arguments.length, values = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
62
|
+
values[_key2] = arguments[_key2];
|
|
63
|
+
}
|
|
64
|
+
var ids = values.find(function (value) {
|
|
65
|
+
return Array.isArray(value);
|
|
66
|
+
});
|
|
67
|
+
return Array.isArray(ids) ? _toConsumableArray(ids) : undefined;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 在接口权威命中结果后追加本地应用及最终选中的 Data Variant ID。
|
|
72
|
+
* 以字符串身份去重,同时将新增 ID 归一为正整数。
|
|
73
|
+
*/
|
|
74
|
+
function appendDataVariantIds(base) {
|
|
75
|
+
var result = Array.isArray(base) ? _toConsumableArray(base) : [];
|
|
76
|
+
var seen = new Set(result.map(function (id) {
|
|
77
|
+
return String(id);
|
|
78
|
+
}));
|
|
79
|
+
for (var _len3 = arguments.length, values = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
|
|
80
|
+
values[_key3 - 1] = arguments[_key3];
|
|
81
|
+
}
|
|
82
|
+
for (var _i = 0, _values = values; _i < _values.length; _i++) {
|
|
83
|
+
var value = _values[_i];
|
|
84
|
+
var candidates = Array.isArray(value) ? value : [value];
|
|
85
|
+
var _iterator = _createForOfIteratorHelper(candidates),
|
|
86
|
+
_step;
|
|
87
|
+
try {
|
|
88
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
89
|
+
var candidate = _step.value;
|
|
90
|
+
var id = Number(candidate);
|
|
91
|
+
if (!Number.isFinite(id) || id <= 0 || seen.has(String(id))) continue;
|
|
92
|
+
result.push(id);
|
|
93
|
+
seen.add(String(id));
|
|
94
|
+
}
|
|
95
|
+
} catch (err) {
|
|
96
|
+
_iterator.e(err);
|
|
97
|
+
} finally {
|
|
98
|
+
_iterator.f();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return Array.isArray(base) || result.length ? result : undefined;
|
|
102
|
+
}
|
|
48
103
|
function normalizeOptionItems(optionItems) {
|
|
49
104
|
if (!Array.isArray(optionItems)) return [];
|
|
50
105
|
return optionItems.map(function (optionItem) {
|
|
@@ -108,7 +163,7 @@ function findVariantById(origin, variantId) {
|
|
|
108
163
|
* 注意:这里不生成 identity,缺省时由 OrderModule 自动补齐。
|
|
109
164
|
*/
|
|
110
165
|
export function transformBaseProductToOrderProduct(params) {
|
|
111
|
-
var _ref10, _ref11, _ref12, _payload$product_id, _ref13, _ref14, _payload$product_vari, _payload$_origin, _payload$_origin2, _ref15, _findVariantById, _origin$production_co, _ref16, _ref17, _ref18, _ref19, _ref20, _matchedVariant$price, _ref21, _ref22, _payload$price, _ref23, _payload$line_total, _payload$
|
|
166
|
+
var _ref10, _ref11, _ref12, _payload$product_id, _ref13, _ref14, _payload$product_vari, _payload$_origin, _payload$_origin2, _payload$metadata, _sourceProduct$metada, _callbackOrigin$metad, _origin$metadata, _payload$metadata2, _payload$_extend, _sourceProduct$metada2, _sourceProduct$_exten, _callbackOrigin$metad2, _callbackOrigin$_exte, _payload$_dataVariant, _sourceProduct$_dataV, _callbackOrigin$_data, _origin$_dataVariant, _ref15, _findVariantById, _origin$production_co, _ref16, _ref17, _ref18, _ref19, _ref20, _matchedVariant$price, _ref21, _ref22, _payload$price, _ref23, _payload$line_total, _payload$_extend2, _ref24, _ref25, _payload$product_sku$, _payload$product_sku, _payload$bundle, _payload$quantity, _payload$_extend3, _extend, _extend2, _ref26, _ref27, _origin$base_price, _ref28, _ref29, _payload$line_total2, _payload$_extend4, _payload$_extend5, _extend3, _payload$_extend6, _payload$_extend7, _ref30, _ref31, _payload$tax_fee, _ref32, _ref33, _payload$is_charge_ta;
|
|
112
167
|
var payload = params.payload,
|
|
113
168
|
_params$fallbackProdu = params.fallbackProductId,
|
|
114
169
|
fallbackProductId = _params$fallbackProdu === void 0 ? null : _params$fallbackProdu;
|
|
@@ -119,6 +174,10 @@ export function transformBaseProductToOrderProduct(params) {
|
|
|
119
174
|
var productVariantId = toNumber((_ref13 = (_ref14 = (_payload$product_vari = payload.product_variant_id) !== null && _payload$product_vari !== void 0 ? _payload$product_vari : payload.variant_id) !== null && _ref14 !== void 0 ? _ref14 : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.product_variant_id) !== null && _ref13 !== void 0 ? _ref13 : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.variant_id, 0);
|
|
120
175
|
var callbackOrigin = payload.origin || ((_payload$_origin = payload._origin) === null || _payload$_origin === void 0 ? void 0 : _payload$_origin.sourceProduct) || ((_payload$_origin2 = payload._origin) === null || _payload$_origin2 === void 0 ? void 0 : _payload$_origin2.sourceItem) || payload._origin || {};
|
|
121
176
|
var origin = _objectSpread(_objectSpread({}, sourceProduct || {}), callbackOrigin || {});
|
|
177
|
+
var authoritativeDataVariantIds = cloneFirstDataVariantIds((_payload$metadata = payload.metadata) === null || _payload$metadata === void 0 ? void 0 : _payload$metadata.data_variant_ids, sourceProduct === null || sourceProduct === void 0 || (_sourceProduct$metada = sourceProduct.metadata) === null || _sourceProduct$metada === void 0 ? void 0 : _sourceProduct$metada.data_variant_ids, callbackOrigin === null || callbackOrigin === void 0 || (_callbackOrigin$metad = callbackOrigin.metadata) === null || _callbackOrigin$metad === void 0 ? void 0 : _callbackOrigin$metad.data_variant_ids, origin === null || origin === void 0 || (_origin$metadata = origin.metadata) === null || _origin$metadata === void 0 ? void 0 : _origin$metadata.data_variant_ids);
|
|
178
|
+
var selectedSettlementSnapshot = firstNonBlank(payload.selected_settlement_snapshot, (_payload$metadata2 = payload.metadata) === null || _payload$metadata2 === void 0 ? void 0 : _payload$metadata2.selected_settlement_snapshot, (_payload$_extend = payload._extend) === null || _payload$_extend === void 0 || (_payload$_extend = _payload$_extend.metadata) === null || _payload$_extend === void 0 ? void 0 : _payload$_extend.selected_settlement_snapshot, sourceProduct === null || sourceProduct === void 0 || (_sourceProduct$metada2 = sourceProduct.metadata) === null || _sourceProduct$metada2 === void 0 ? void 0 : _sourceProduct$metada2.selected_settlement_snapshot, sourceProduct === null || sourceProduct === void 0 || (_sourceProduct$_exten = sourceProduct._extend) === null || _sourceProduct$_exten === void 0 || (_sourceProduct$_exten = _sourceProduct$_exten.metadata) === null || _sourceProduct$_exten === void 0 ? void 0 : _sourceProduct$_exten.selected_settlement_snapshot, callbackOrigin === null || callbackOrigin === void 0 || (_callbackOrigin$metad2 = callbackOrigin.metadata) === null || _callbackOrigin$metad2 === void 0 ? void 0 : _callbackOrigin$metad2.selected_settlement_snapshot, callbackOrigin === null || callbackOrigin === void 0 || (_callbackOrigin$_exte = callbackOrigin._extend) === null || _callbackOrigin$_exte === void 0 || (_callbackOrigin$_exte = _callbackOrigin$_exte.metadata) === null || _callbackOrigin$_exte === void 0 ? void 0 : _callbackOrigin$_exte.selected_settlement_snapshot);
|
|
179
|
+
var locallyAppliedVariantIds = authoritativeDataVariantIds === undefined ? cloneFirstDataVariantIds((_payload$_dataVariant = payload._dataVariant) === null || _payload$_dataVariant === void 0 ? void 0 : _payload$_dataVariant.appliedVariantIds, sourceProduct === null || sourceProduct === void 0 || (_sourceProduct$_dataV = sourceProduct._dataVariant) === null || _sourceProduct$_dataV === void 0 ? void 0 : _sourceProduct$_dataV.appliedVariantIds, callbackOrigin === null || callbackOrigin === void 0 || (_callbackOrigin$_data = callbackOrigin._dataVariant) === null || _callbackOrigin$_data === void 0 ? void 0 : _callbackOrigin$_data.appliedVariantIds, origin === null || origin === void 0 || (_origin$_dataVariant = origin._dataVariant) === null || _origin$_dataVariant === void 0 ? void 0 : _origin$_dataVariant.appliedVariantIds) : undefined;
|
|
180
|
+
var dataVariantIds = appendDataVariantIds(authoritativeDataVariantIds, locallyAppliedVariantIds, selectedSettlementSnapshot === null || selectedSettlementSnapshot === void 0 ? void 0 : selectedSettlementSnapshot.data_variant_id);
|
|
122
181
|
var matchedVariant = (_ref15 = (_findVariantById = findVariantById(callbackOrigin, productVariantId)) !== null && _findVariantById !== void 0 ? _findVariantById : findVariantById(sourceProduct, productVariantId)) !== null && _ref15 !== void 0 ? _ref15 : findVariantById(origin, productVariantId);
|
|
123
182
|
var productionCode = normalizeProductionCode(Object.prototype.hasOwnProperty.call(payload, 'production_code') ? payload.production_code : productVariantId > 0 ? matchedVariant === null || matchedVariant === void 0 ? void 0 : matchedVariant.production_code : (_origin$production_co = origin === null || origin === void 0 ? void 0 : origin.production_code) !== null && _origin$production_co !== void 0 ? _origin$production_co : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.production_code);
|
|
124
183
|
var hasPriceOverride = payload.price_override !== undefined && payload.price_override !== null && payload.price_override !== '';
|
|
@@ -126,7 +185,7 @@ export function transformBaseProductToOrderProduct(params) {
|
|
|
126
185
|
// 此时优先从商品/variant 快照读取目录价;售价仍由 line_total - bundle 推导。
|
|
127
186
|
var catalogSourcePrice = (_ref16 = (_ref17 = (_ref18 = (_ref19 = (_ref20 = (_matchedVariant$price = matchedVariant === null || matchedVariant === void 0 ? void 0 : matchedVariant.price) !== null && _matchedVariant$price !== void 0 ? _matchedVariant$price : matchedVariant === null || matchedVariant === void 0 ? void 0 : matchedVariant.base_price) !== null && _ref20 !== void 0 ? _ref20 : origin === null || origin === void 0 ? void 0 : origin.price) !== null && _ref19 !== void 0 ? _ref19 : origin === null || origin === void 0 ? void 0 : origin.base_price) !== null && _ref18 !== void 0 ? _ref18 : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.price) !== null && _ref17 !== void 0 ? _ref17 : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.selling_price) !== null && _ref16 !== void 0 ? _ref16 : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.base_price;
|
|
128
187
|
var sourceProductPrice = toPriceString(hasPriceOverride ? (_ref21 = catalogSourcePrice !== null && catalogSourcePrice !== void 0 ? catalogSourcePrice : payload.price) !== null && _ref21 !== void 0 ? _ref21 : payload.selling_price : (_ref22 = (_payload$price = payload.price) !== null && _payload$price !== void 0 ? _payload$price : payload.selling_price) !== null && _ref22 !== void 0 ? _ref22 : catalogSourcePrice, '0.00');
|
|
129
|
-
var explicitLineTotal = (_ref23 = (_payload$line_total = payload.line_total) !== null && _payload$line_total !== void 0 ? _payload$line_total : payload.total) !== null && _ref23 !== void 0 ? _ref23 : (_payload$
|
|
188
|
+
var explicitLineTotal = (_ref23 = (_payload$line_total = payload.line_total) !== null && _payload$line_total !== void 0 ? _payload$line_total : payload.total) !== null && _ref23 !== void 0 ? _ref23 : (_payload$_extend2 = payload._extend) === null || _payload$_extend2 === void 0 ? void 0 : _payload$_extend2.total;
|
|
130
189
|
var hasExplicitLineTotal = Number.isFinite(Number(explicitLineTotal));
|
|
131
190
|
var lineCompositeTotal = toPriceString(explicitLineTotal, sourceProductPrice);
|
|
132
191
|
var productOptionItem = normalizeProductSkuOptions(normalizeOptionItems((_ref24 = (_ref25 = (_payload$product_sku$ = (_payload$product_sku = payload.product_sku) === null || _payload$product_sku === void 0 ? void 0 : _payload$product_sku.option) !== null && _payload$product_sku$ !== void 0 ? _payload$product_sku$ : payload.option) !== null && _ref25 !== void 0 ? _ref25 : payload.options) !== null && _ref24 !== void 0 ? _ref24 : payload.product_option_item));
|
|
@@ -137,16 +196,16 @@ export function transformBaseProductToOrderProduct(params) {
|
|
|
137
196
|
var resolvedQuantity = toSafePositiveInt((_payload$quantity = payload.quantity) !== null && _payload$quantity !== void 0 ? _payload$quantity : payload.num, 1);
|
|
138
197
|
var originTotal = resolveManualDiscountOriginTotal({
|
|
139
198
|
originTotal: payload.origin_total,
|
|
140
|
-
extendOriginTotal: (_payload$
|
|
199
|
+
extendOriginTotal: (_payload$_extend3 = payload._extend) === null || _payload$_extend3 === void 0 ? void 0 : _payload$_extend3.origin_total,
|
|
141
200
|
originExtendOriginTotal: origin === null || origin === void 0 || (_extend = origin._extend) === null || _extend === void 0 ? void 0 : _extend.origin_total,
|
|
142
201
|
sourceExtendOriginTotal: sourceProduct === null || sourceProduct === void 0 || (_extend2 = sourceProduct._extend) === null || _extend2 === void 0 ? void 0 : _extend2.origin_total,
|
|
143
202
|
catalogUnitPrice: (_ref26 = (_ref27 = (_origin$base_price = origin === null || origin === void 0 ? void 0 : origin.base_price) !== null && _origin$base_price !== void 0 ? _origin$base_price : origin === null || origin === void 0 ? void 0 : origin.price) !== null && _ref27 !== void 0 ? _ref27 : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.base_price) !== null && _ref26 !== void 0 ? _ref26 : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.price,
|
|
144
203
|
quantity: resolvedQuantity
|
|
145
204
|
});
|
|
146
|
-
var sellingTotal = Number((_ref28 = (_ref29 = (_payload$line_total2 = payload.line_total) !== null && _payload$line_total2 !== void 0 ? _payload$line_total2 : payload.total) !== null && _ref29 !== void 0 ? _ref29 : (_payload$
|
|
205
|
+
var sellingTotal = Number((_ref28 = (_ref29 = (_payload$line_total2 = payload.line_total) !== null && _payload$line_total2 !== void 0 ? _payload$line_total2 : payload.total) !== null && _ref29 !== void 0 ? _ref29 : (_payload$_extend4 = payload._extend) === null || _payload$_extend4 === void 0 ? void 0 : _payload$_extend4.total) !== null && _ref28 !== void 0 ? _ref28 : lineCompositeTotal);
|
|
147
206
|
var discountReason = resolveManualDiscountReasonFromSources({
|
|
148
207
|
discountReason: payload.discount_reason,
|
|
149
|
-
extendDiscountReason: (_payload$
|
|
208
|
+
extendDiscountReason: (_payload$_extend5 = payload._extend) === null || _payload$_extend5 === void 0 ? void 0 : _payload$_extend5.discount_reason,
|
|
150
209
|
originExtendDiscountReason: origin === null || origin === void 0 || (_extend3 = origin._extend) === null || _extend3 === void 0 ? void 0 : _extend3.discount_reason
|
|
151
210
|
});
|
|
152
211
|
var lineOriginalPrice = hasPriceOverride && Number.isFinite(originTotal) ? toPriceString(originTotal) : lineCompositeTotal;
|
|
@@ -159,8 +218,8 @@ export function transformBaseProductToOrderProduct(params) {
|
|
|
159
218
|
sellingTotal: Number.isFinite(sellingTotal) ? sellingTotal : Number(lineCompositeTotal),
|
|
160
219
|
quantity: resolvedQuantity,
|
|
161
220
|
message: discountReason,
|
|
162
|
-
discountway: (_payload$
|
|
163
|
-
discount_per: (_payload$
|
|
221
|
+
discountway: (_payload$_extend6 = payload._extend) === null || _payload$_extend6 === void 0 ? void 0 : _payload$_extend6.discountway,
|
|
222
|
+
discount_per: (_payload$_extend7 = payload._extend) === null || _payload$_extend7 === void 0 ? void 0 : _payload$_extend7.discount_per
|
|
164
223
|
})) : payload.discount_list || [];
|
|
165
224
|
|
|
166
225
|
// v2:source 不含 option;main_product_* 含 option(与 normalizeOrderProduct 一致)
|
|
@@ -172,7 +231,7 @@ export function transformBaseProductToOrderProduct(params) {
|
|
|
172
231
|
});
|
|
173
232
|
var derivedMainSelling = hasExplicitLineTotal ? Number(lineCompositeTotal) - Number(bundleOnlyComposite) : Number(mainProductOriginalPrice);
|
|
174
233
|
var mainProductSellingPrice = toPriceString(Number.isFinite(derivedMainSelling) && derivedMainSelling >= 0 ? derivedMainSelling : Number(mainProductOriginalPrice));
|
|
175
|
-
var metadata = _objectSpread(_objectSpread({
|
|
234
|
+
var metadata = _objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
176
235
|
unique: payload.unique,
|
|
177
236
|
session: payload.session,
|
|
178
237
|
form: payload.form,
|
|
@@ -187,7 +246,11 @@ export function transformBaseProductToOrderProduct(params) {
|
|
|
187
246
|
main_product_original_price: mainProductOriginalPrice,
|
|
188
247
|
price_schema_version: 2,
|
|
189
248
|
holder_config: sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.holder_config
|
|
190
|
-
},
|
|
249
|
+
}, dataVariantIds !== undefined ? {
|
|
250
|
+
data_variant_ids: dataVariantIds
|
|
251
|
+
} : {}), selectedSettlementSnapshot ? {
|
|
252
|
+
selected_settlement_snapshot: selectedSettlementSnapshot
|
|
253
|
+
} : {}), hasPriceOverride ? {
|
|
191
254
|
price_override: String(payload.price_override),
|
|
192
255
|
is_manual_discount: 1
|
|
193
256
|
} : {}), payload.bundle_edit !== undefined ? {
|
|
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
326
326
|
date: string;
|
|
327
327
|
status: string;
|
|
328
328
|
week: string;
|
|
329
|
-
weekNum: 0 | 1 | 2 |
|
|
329
|
+
weekNum: 0 | 1 | 2 | 5 | 4 | 3 | 6;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -345,7 +345,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
345
345
|
count: number;
|
|
346
346
|
left: number;
|
|
347
347
|
summaryCount: number;
|
|
348
|
-
status: "
|
|
348
|
+
status: "sold_out" | "lots_of_space" | "filling_up_fast";
|
|
349
349
|
}[];
|
|
350
350
|
/**
|
|
351
351
|
* 找到多个资源的公共可用时间段
|
|
@@ -319,7 +319,7 @@ export function transformDetailToProductAndBooking(cacheItem, ctx) {
|
|
|
319
319
|
* 把 cacheItem._extend.other 中的字段 + 顶层运行态拼成 `BaseProductDetailPayload`。
|
|
320
320
|
*/
|
|
321
321
|
function buildBasePayloadFromCacheItem(cacheItem, ctx) {
|
|
322
|
-
var _cacheItem$_extend, _cacheItem$_extend$qu, _cacheItem$_extend2, _cacheItem$product_id, _cacheItem$id, _ref5, _other$product_varian, _other$production_cod, _extend$skuValue, _extend$_skuValue, _extend$price, _extend$price2;
|
|
322
|
+
var _cacheItem$_extend, _cacheItem$_extend$qu, _cacheItem$_extend2, _cacheItem$product_id, _cacheItem$id, _ref5, _other$product_varian, _other$production_cod, _extend$skuValue, _extend$_skuValue, _extend$price, _extend$price2, _cacheItem$metadata$s, _cacheItem$metadata, _extend$metadata;
|
|
323
323
|
var other = (cacheItem === null || cacheItem === void 0 || (_cacheItem$_extend = cacheItem._extend) === null || _cacheItem$_extend === void 0 ? void 0 : _cacheItem$_extend.other) || {};
|
|
324
324
|
var quantity = (ctx === null || ctx === void 0 ? void 0 : ctx.quantity) != null && ctx.quantity > 0 ? ctx.quantity : (_cacheItem$_extend$qu = cacheItem === null || cacheItem === void 0 || (_cacheItem$_extend2 = cacheItem._extend) === null || _cacheItem$_extend2 === void 0 ? void 0 : _cacheItem$_extend2.quantity) !== null && _cacheItem$_extend$qu !== void 0 ? _cacheItem$_extend$qu : 1;
|
|
325
325
|
var resolvedPid = (_cacheItem$product_id = cacheItem === null || cacheItem === void 0 ? void 0 : cacheItem.product_id) !== null && _cacheItem$product_id !== void 0 ? _cacheItem$product_id : cacheItem === null || cacheItem === void 0 ? void 0 : cacheItem.id;
|
|
@@ -350,6 +350,7 @@ function buildBasePayloadFromCacheItem(cacheItem, ctx) {
|
|
|
350
350
|
bundle_edit: extend === null || extend === void 0 ? void 0 : extend.bundle_edit,
|
|
351
351
|
discount_reason: extend === null || extend === void 0 ? void 0 : extend.discount_reason,
|
|
352
352
|
discount_list: cacheItem === null || cacheItem === void 0 ? void 0 : cacheItem.discount_list,
|
|
353
|
+
selected_settlement_snapshot: (_cacheItem$metadata$s = cacheItem === null || cacheItem === void 0 || (_cacheItem$metadata = cacheItem.metadata) === null || _cacheItem$metadata === void 0 ? void 0 : _cacheItem$metadata.selected_settlement_snapshot) !== null && _cacheItem$metadata$s !== void 0 ? _cacheItem$metadata$s : extend === null || extend === void 0 || (_extend$metadata = extend.metadata) === null || _extend$metadata === void 0 ? void 0 : _extend$metadata.selected_settlement_snapshot,
|
|
353
354
|
_extend: extend
|
|
354
355
|
};
|
|
355
356
|
}
|
|
@@ -3,7 +3,7 @@ import type { ConditionScope, DataVariantBusinessData, DataVariantMenu, DataVari
|
|
|
3
3
|
/**
|
|
4
4
|
* Data Variant 评估器。
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* OS Server 商品路由开启时由 ProductsModule 调用;路由关闭时由 ProductList 在远端响应后调用。
|
|
7
7
|
*/
|
|
8
8
|
export declare class DataVariantEvaluator {
|
|
9
9
|
private adapter;
|
|
@@ -17,7 +17,7 @@ export declare class DataVariantEvaluator {
|
|
|
17
17
|
/**
|
|
18
18
|
* 批量解析商品 Data Variant。
|
|
19
19
|
*
|
|
20
|
-
*
|
|
20
|
+
* 优先使用商品 metadata.data_variant_ids;缺少权威命中结果时才执行本地策略判断。
|
|
21
21
|
*/
|
|
22
22
|
resolveProducts(businessData: DataVariantBusinessData): ResolvedDataVariantResult;
|
|
23
23
|
/**
|
|
@@ -34,8 +34,24 @@ export declare class DataVariantEvaluator {
|
|
|
34
34
|
* 这里不依赖餐牌,只读取策略配置和调用方传入的 scheduleList。
|
|
35
35
|
*/
|
|
36
36
|
buildScheduleTimePoints(strategyConfigs: StrategyConfig<DataVariantRuleMetadata>[], scheduleList: NonNullable<DataVariantBusinessData['scheduleList']>): string[];
|
|
37
|
+
/**
|
|
38
|
+
* 判断商品(含套餐子商品)是否仍需要本地执行策略条件。
|
|
39
|
+
* metadata.data_variant_ids 只要是数组,即使为空,也表示接口已经给出权威命中结果。
|
|
40
|
+
*/
|
|
41
|
+
private requiresLocalStrategyEvaluation;
|
|
42
|
+
/**
|
|
43
|
+
* 将接口返回的高 -> 低优先级 Variant ID 转成数值优先级。
|
|
44
|
+
* 返回 null 表示接口没有提供该字段;空 Map 表示已计算但没有任何命中。
|
|
45
|
+
*/
|
|
46
|
+
private getAuthoritativeVariantPriorities;
|
|
47
|
+
private normalizeDataVariantId;
|
|
37
48
|
private buildGlobalEffectiveRuleMap;
|
|
38
49
|
private resolveProduct;
|
|
50
|
+
/**
|
|
51
|
+
* 多货币 Data Variant 只生成候选列表,不参与商品字段覆盖。
|
|
52
|
+
* rule_id=0 是无条件默认价;同币种命中的条件价优先于默认价。
|
|
53
|
+
*/
|
|
54
|
+
private resolveSettlementOptions;
|
|
39
55
|
/**
|
|
40
56
|
* 解析套餐子商品上的 Data Variant 覆盖。
|
|
41
57
|
*
|
|
@@ -10,7 +10,7 @@ var _adapter = require("./adapter");
|
|
|
10
10
|
/**
|
|
11
11
|
* Data Variant 评估器。
|
|
12
12
|
*
|
|
13
|
-
*
|
|
13
|
+
* OS Server 商品路由开启时由 ProductsModule 调用;路由关闭时由 ProductList 在远端响应后调用。
|
|
14
14
|
*/
|
|
15
15
|
class DataVariantEvaluator {
|
|
16
16
|
adapter;
|
|
@@ -32,16 +32,22 @@ class DataVariantEvaluator {
|
|
|
32
32
|
/**
|
|
33
33
|
* 批量解析商品 Data Variant。
|
|
34
34
|
*
|
|
35
|
-
*
|
|
35
|
+
* 优先使用商品 metadata.data_variant_ids;缺少权威命中结果时才执行本地策略判断。
|
|
36
36
|
*/
|
|
37
37
|
resolveProducts(businessData) {
|
|
38
38
|
const strategyConfigs = businessData.strategyConfigs ? this.normalizeStrategyConfigs(businessData.strategyConfigs) : this.strategyConfigs;
|
|
39
39
|
const menuScopeMap = this.buildMenuScopeMap(businessData.menuList || []);
|
|
40
40
|
const scheduleTimePoints = this.buildScheduleTimePoints(strategyConfigs, businessData.scheduleList || []);
|
|
41
|
+
// metadata.data_variant_ids 存在时,接口已经完成规则计算;只有仍有商品缺少
|
|
42
|
+
// 该权威结果时才初始化本地策略引擎,避免 OS/接口与客户端重复评估。
|
|
43
|
+
const shouldEvaluateStrategies = businessData.products.some(product => this.requiresLocalStrategyEvaluation(product));
|
|
41
44
|
const {
|
|
42
45
|
globalEffectiveRuleMap,
|
|
43
46
|
rawResults
|
|
44
|
-
} = this.buildGlobalEffectiveRuleMap(strategyConfigs, businessData, menuScopeMap)
|
|
47
|
+
} = shouldEvaluateStrategies ? this.buildGlobalEffectiveRuleMap(strategyConfigs, businessData, menuScopeMap) : {
|
|
48
|
+
globalEffectiveRuleMap: new Map(),
|
|
49
|
+
rawResults: []
|
|
50
|
+
};
|
|
45
51
|
const products = businessData.products.map(product => {
|
|
46
52
|
const resolvedProduct = this.resolveProduct(product, businessData, globalEffectiveRuleMap, menuScopeMap);
|
|
47
53
|
// 套餐子商品也可能携带 data_variants,需在同一策略上下文内继续评估并写回 bundle_item。
|
|
@@ -124,6 +130,46 @@ class DataVariantEvaluator {
|
|
|
124
130
|
const matchedSchedules = scheduleList.filter(schedule => scheduleIdSet.has(Number(schedule.id)));
|
|
125
131
|
return this.extractTimePointsFromSchedules(matchedSchedules);
|
|
126
132
|
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 判断商品(含套餐子商品)是否仍需要本地执行策略条件。
|
|
136
|
+
* metadata.data_variant_ids 只要是数组,即使为空,也表示接口已经给出权威命中结果。
|
|
137
|
+
*/
|
|
138
|
+
requiresLocalStrategyEvaluation(product) {
|
|
139
|
+
const dataVariants = this.getProductDataVariants(product);
|
|
140
|
+
const hasConditionalVariant = dataVariants.some(variant => Number(variant.data_variant_rule_id) !== 0);
|
|
141
|
+
if (hasConditionalVariant && this.getAuthoritativeVariantPriorities(product) === null) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
const bundleGroups = Array.isArray(product.bundle_group) ? product.bundle_group : [];
|
|
145
|
+
return bundleGroups.some(group => {
|
|
146
|
+
const bundleItems = Array.isArray(group?.bundle_item) ? group.bundle_item : [];
|
|
147
|
+
return bundleItems.some(item => this.requiresLocalStrategyEvaluation(this.toBundleItemDataVariantProduct(item)));
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* 将接口返回的高 -> 低优先级 Variant ID 转成数值优先级。
|
|
153
|
+
* 返回 null 表示接口没有提供该字段;空 Map 表示已计算但没有任何命中。
|
|
154
|
+
*/
|
|
155
|
+
getAuthoritativeVariantPriorities(product) {
|
|
156
|
+
const rawIds = product?.metadata?.data_variant_ids;
|
|
157
|
+
if (!Array.isArray(rawIds)) return null;
|
|
158
|
+
const orderedIds = [];
|
|
159
|
+
const seen = new Set();
|
|
160
|
+
for (const rawId of rawIds) {
|
|
161
|
+
const id = this.normalizeDataVariantId(rawId);
|
|
162
|
+
if (id === null || seen.has(id)) continue;
|
|
163
|
+
seen.add(id);
|
|
164
|
+
orderedIds.push(id);
|
|
165
|
+
}
|
|
166
|
+
return new Map(orderedIds.map((id, index) => [id, orderedIds.length - index]));
|
|
167
|
+
}
|
|
168
|
+
normalizeDataVariantId(value) {
|
|
169
|
+
if (value === undefined || value === null) return null;
|
|
170
|
+
const normalized = String(value).trim();
|
|
171
|
+
return normalized || null;
|
|
172
|
+
}
|
|
127
173
|
buildGlobalEffectiveRuleMap(strategyConfigs, businessData, menuScopeMap) {
|
|
128
174
|
const globalEffectiveRuleMap = new Map();
|
|
129
175
|
const rawResults = [];
|
|
@@ -155,7 +201,22 @@ class DataVariantEvaluator {
|
|
|
155
201
|
const dataVariants = this.getProductDataVariants(product);
|
|
156
202
|
if (!dataVariants.length) return product;
|
|
157
203
|
const matchedVariants = [];
|
|
204
|
+
const authoritativeVariantPriorities = this.getAuthoritativeVariantPriorities(product);
|
|
205
|
+
const settlementVariants = dataVariants.filter(variant => variant.business_type === 'multi_currency_settlement' && variant.status === 'enable');
|
|
158
206
|
for (const variant of dataVariants) {
|
|
207
|
+
if (variant.business_type === 'multi_currency_settlement') continue;
|
|
208
|
+
if (authoritativeVariantPriorities !== null) {
|
|
209
|
+
const variantId = this.normalizeDataVariantId(variant.id);
|
|
210
|
+
const priority = variantId === null ? undefined : authoritativeVariantPriorities.get(variantId);
|
|
211
|
+
if (priority === undefined) continue;
|
|
212
|
+
matchedVariants.push({
|
|
213
|
+
ruleId: String(variant.data_variant_rule_id),
|
|
214
|
+
priority,
|
|
215
|
+
data: variant.data || {},
|
|
216
|
+
variant
|
|
217
|
+
});
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
159
220
|
const rule = globalEffectiveRuleMap.get(String(variant.data_variant_rule_id));
|
|
160
221
|
if (!rule) continue;
|
|
161
222
|
if (!this.evaluateProductRules(rule, product, businessData, menuScopeMap)) {
|
|
@@ -168,8 +229,76 @@ class DataVariantEvaluator {
|
|
|
168
229
|
variant
|
|
169
230
|
});
|
|
170
231
|
}
|
|
171
|
-
|
|
172
|
-
|
|
232
|
+
const resolvedProduct = matchedVariants.length ? this.mergeMatchedVariants(product, matchedVariants) : product;
|
|
233
|
+
const availableSettlementOptions = this.resolveSettlementOptions(settlementVariants, product, businessData, globalEffectiveRuleMap, menuScopeMap, authoritativeVariantPriorities);
|
|
234
|
+
if (!settlementVariants.length) return resolvedProduct;
|
|
235
|
+
return {
|
|
236
|
+
...resolvedProduct,
|
|
237
|
+
available_settlement_options: availableSettlementOptions
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* 多货币 Data Variant 只生成候选列表,不参与商品字段覆盖。
|
|
243
|
+
* rule_id=0 是无条件默认价;同币种命中的条件价优先于默认价。
|
|
244
|
+
*/
|
|
245
|
+
resolveSettlementOptions(variants, product, businessData, globalEffectiveRuleMap, menuScopeMap, authoritativeVariantPriorities) {
|
|
246
|
+
if (!variants.length) return [];
|
|
247
|
+
const candidates = variants.flatMap(variant => {
|
|
248
|
+
const settlement = variant.data?.multi_currency_settlement;
|
|
249
|
+
if (!settlement || typeof settlement !== 'object') return [];
|
|
250
|
+
const ruleId = String(variant.data_variant_rule_id);
|
|
251
|
+
const isDefault = Number(variant.data_variant_rule_id) === 0;
|
|
252
|
+
const rule = isDefault ? undefined : globalEffectiveRuleMap.get(ruleId);
|
|
253
|
+
const variantId = this.normalizeDataVariantId(variant.id);
|
|
254
|
+
const authoritativePriority = variantId === null ? undefined : authoritativeVariantPriorities?.get(variantId);
|
|
255
|
+
let available;
|
|
256
|
+
let priority;
|
|
257
|
+
if (isDefault) {
|
|
258
|
+
// rule 0 是无条件默认候选,不依赖接口命中 ID 或本地策略引擎。
|
|
259
|
+
available = true;
|
|
260
|
+
priority = Number.NEGATIVE_INFINITY;
|
|
261
|
+
} else if (authoritativeVariantPriorities !== null) {
|
|
262
|
+
// 数组存在(包括 [])即表示接口已经算过规则,不再在客户端二次判断。
|
|
263
|
+
available = authoritativePriority !== undefined;
|
|
264
|
+
priority = authoritativePriority ?? rule?.priority ?? Number.NEGATIVE_INFINITY;
|
|
265
|
+
} else {
|
|
266
|
+
available = Boolean(rule && this.evaluateProductRules(rule, product, businessData, menuScopeMap));
|
|
267
|
+
priority = rule?.priority ?? Number.NEGATIVE_INFINITY;
|
|
268
|
+
}
|
|
269
|
+
const settlementType = String(settlement.settlement_type || '');
|
|
270
|
+
const currencyProductId = this.toNumber(settlement.currency_product_id);
|
|
271
|
+
const settlementKey = settlementType === 'virtual_currency' ? `virtual_currency:${currencyProductId || ''}` : settlementType || `variant:${variant.id ?? ruleId}`;
|
|
272
|
+
return [{
|
|
273
|
+
key: settlementKey,
|
|
274
|
+
priority,
|
|
275
|
+
isDefault,
|
|
276
|
+
option: {
|
|
277
|
+
...settlement,
|
|
278
|
+
settlement_type: settlementType,
|
|
279
|
+
...(currencyProductId ? {
|
|
280
|
+
currency_product_id: currencyProductId
|
|
281
|
+
} : {}),
|
|
282
|
+
price: String(variant.data?.price ?? '0'),
|
|
283
|
+
data_variant_id: variant.id,
|
|
284
|
+
data_variant_rule_id: variant.data_variant_rule_id,
|
|
285
|
+
available,
|
|
286
|
+
disabled_reason: available ? '' : String(settlement.disabled_reason || 'Not available for this purchase.')
|
|
287
|
+
}
|
|
288
|
+
}];
|
|
289
|
+
});
|
|
290
|
+
const grouped = new Map();
|
|
291
|
+
for (const candidate of candidates) {
|
|
292
|
+
const group = grouped.get(candidate.key) || [];
|
|
293
|
+
group.push(candidate);
|
|
294
|
+
grouped.set(candidate.key, group);
|
|
295
|
+
}
|
|
296
|
+
return Array.from(grouped.values()).map(group => {
|
|
297
|
+
const matchedConditional = group.filter(candidate => !candidate.isDefault && candidate.option.available).sort((a, b) => b.priority - a.priority)[0];
|
|
298
|
+
const defaultCandidate = group.find(candidate => candidate.isDefault);
|
|
299
|
+
const unavailableCandidate = [...group].filter(candidate => !candidate.option.available).sort((a, b) => b.priority - a.priority)[0];
|
|
300
|
+
return (matchedConditional || defaultCandidate || unavailableCandidate).option;
|
|
301
|
+
});
|
|
173
302
|
}
|
|
174
303
|
|
|
175
304
|
/**
|
|
@@ -222,7 +351,8 @@ class DataVariantEvaluator {
|
|
|
222
351
|
product_variant_id: variantId,
|
|
223
352
|
variant_id: variantId,
|
|
224
353
|
collection: item.collection,
|
|
225
|
-
data_variants: item.data_variants
|
|
354
|
+
data_variants: item.data_variants,
|
|
355
|
+
metadata: item.metadata
|
|
226
356
|
};
|
|
227
357
|
}
|
|
228
358
|
|
|
@@ -453,6 +583,7 @@ class DataVariantEvaluator {
|
|
|
453
583
|
}
|
|
454
584
|
result._dataVariant = {
|
|
455
585
|
appliedRuleIds,
|
|
586
|
+
appliedVariantIds: Array.from(new Set([...sortedVariants].reverse().map(matched => this.normalizeDataVariantId(matched.variant.id)).filter(id => id !== null))),
|
|
456
587
|
appliedFields: Array.from(appliedFields),
|
|
457
588
|
original
|
|
458
589
|
};
|
|
@@ -35,6 +35,10 @@ export interface DataVariantItem {
|
|
|
35
35
|
module_data_id?: number;
|
|
36
36
|
/** 关联策略模型 metadata.id / data_variant_rule.id */
|
|
37
37
|
data_variant_rule_id: number | string;
|
|
38
|
+
/** 业务类型;多货币结算候选不会走普通字段覆盖 */
|
|
39
|
+
business_type?: 'multi_currency_settlement' | string;
|
|
40
|
+
/** 数据状态;多货币结算仅处理 enable 记录 */
|
|
41
|
+
status?: 'enable' | 'disable' | string;
|
|
38
42
|
/** 命中策略后需要覆盖到商品上的字段 */
|
|
39
43
|
data: Record<string, any>;
|
|
40
44
|
created_at?: string | null;
|
|
@@ -53,11 +57,30 @@ export interface DataVariantProduct {
|
|
|
53
57
|
id?: number | string;
|
|
54
58
|
[key: string]: any;
|
|
55
59
|
}>;
|
|
60
|
+
/**
|
|
61
|
+
* 商品接口已经完成规则计算时返回的命中结果。
|
|
62
|
+
* 数组按 Data Variant 优先级从高到低排列;空数组表示已计算但无命中。
|
|
63
|
+
*/
|
|
64
|
+
metadata?: {
|
|
65
|
+
data_variant_ids?: Array<number | string>;
|
|
66
|
+
[key: string]: any;
|
|
67
|
+
};
|
|
56
68
|
/** 后端 /product/query with dataVariants 返回的智能定价变体列表 */
|
|
57
69
|
data_variants?: DataVariantItem[];
|
|
70
|
+
/** 当前上下文解析后的可选结算货币,不覆盖商品原始多货币配置 */
|
|
71
|
+
available_settlement_options?: AvailableSettlementOption[];
|
|
58
72
|
_dataVariant?: DataVariantAppliedInfo;
|
|
59
73
|
[key: string]: any;
|
|
60
74
|
}
|
|
75
|
+
export interface AvailableSettlementOption extends Record<string, any> {
|
|
76
|
+
settlement_type: 'legal_currency' | 'virtual_currency' | string;
|
|
77
|
+
currency_product_id?: number;
|
|
78
|
+
price: string;
|
|
79
|
+
data_variant_id?: number;
|
|
80
|
+
data_variant_rule_id: number | string;
|
|
81
|
+
available: boolean;
|
|
82
|
+
disabled_reason?: string;
|
|
83
|
+
}
|
|
61
84
|
/**
|
|
62
85
|
* 餐牌商品配置项。
|
|
63
86
|
*/
|
|
@@ -131,6 +154,8 @@ export interface MatchedDataVariant {
|
|
|
131
154
|
*/
|
|
132
155
|
export interface DataVariantAppliedInfo {
|
|
133
156
|
appliedRuleIds: string[];
|
|
157
|
+
/** 本地策略实际应用的 Data Variant ID,按优先级从高到低排列。 */
|
|
158
|
+
appliedVariantIds?: Array<number | string>;
|
|
134
159
|
appliedFields: string[];
|
|
135
160
|
original: DataVariantProduct;
|
|
136
161
|
}
|
|
@@ -181,6 +181,7 @@ function buildCacheItemFromOrderLine(input) {
|
|
|
181
181
|
booking,
|
|
182
182
|
sourceProduct
|
|
183
183
|
} = input;
|
|
184
|
+
const holderConfig = sourceProduct?.holder_config ?? sourceProduct?.origin?.holder_config ?? product.metadata?.holder_config;
|
|
184
185
|
const resolvedId = product.product_id ?? sourceProduct?.id;
|
|
185
186
|
const selling = Number(product.selling_price ?? 0);
|
|
186
187
|
const original = Number(product.original_price ?? selling);
|
|
@@ -249,6 +250,9 @@ function buildCacheItemFromOrderLine(input) {
|
|
|
249
250
|
}
|
|
250
251
|
const base = {
|
|
251
252
|
...(sourceProduct || {}),
|
|
253
|
+
...(holderConfig !== undefined && holderConfig !== null ? {
|
|
254
|
+
holder_config: holderConfig
|
|
255
|
+
} : {}),
|
|
252
256
|
id: resolvedId,
|
|
253
257
|
product_id: resolvedId,
|
|
254
258
|
extension_type: sourceProduct?.extension_type ?? booking?.product?.extension_type ?? sourceProduct?.extension_type,
|
|
@@ -25,9 +25,11 @@ export declare class DiscountModule extends BaseModule implements Module, Discou
|
|
|
25
25
|
with_wallet_pass_holder: 0 | 1;
|
|
26
26
|
with_available_wallet_flag?: 0 | 1;
|
|
27
27
|
with_available_wallet_pass_flag?: 0 | 1;
|
|
28
|
+
with_virtual_currency?: 0 | 1;
|
|
28
29
|
request_timezone: string;
|
|
29
30
|
order_id?: number | string;
|
|
30
31
|
}): Promise<DiscountPrepareConfigResult>;
|
|
32
|
+
private normalizeVirtualCurrencyList;
|
|
31
33
|
batchSearch(code: string, options?: {
|
|
32
34
|
customerId?: number;
|
|
33
35
|
orderId?: number;
|
|
@@ -80,21 +80,50 @@ class DiscountModule extends _BaseModule.BaseModule {
|
|
|
80
80
|
const prepareConfig = await this.request.post(`/order/prepare/config`, {
|
|
81
81
|
...params,
|
|
82
82
|
with_available_wallet_flag: params.with_available_wallet_flag ?? 1,
|
|
83
|
-
with_available_wallet_pass_flag: params.with_available_wallet_pass_flag ?? 1
|
|
83
|
+
with_available_wallet_pass_flag: params.with_available_wallet_pass_flag ?? 1,
|
|
84
|
+
with_virtual_currency: params.with_virtual_currency ?? 1
|
|
84
85
|
});
|
|
85
86
|
const rawDiscountList = [...(prepareConfig?.data?.good_pass_list || []), ...(prepareConfig?.data?.discount_card_list || [])];
|
|
86
87
|
const availableWalletList = [...(prepareConfig?.data?.avaiable_wallet_list || []), ...(prepareConfig?.data?.available_wallet_list || [])];
|
|
87
88
|
const availableWalletPassList = prepareConfig?.data?.available_wallet_pass_list || [];
|
|
88
89
|
const availableWalletIds = this.normalizePositiveNumberIds([...availableWalletList.map(item => item?.wallet_id), ...availableWalletPassList.map(item => item?.product_id)]);
|
|
90
|
+
const virtualCurrencyList = this.normalizeVirtualCurrencyList(prepareConfig?.data?.virtual_currency_list);
|
|
89
91
|
const goodPassList = this.filterEnabledDiscountList(rawDiscountList) || [];
|
|
90
92
|
|
|
91
93
|
// this.setDiscountList(goodPassList);
|
|
92
94
|
|
|
93
95
|
return {
|
|
94
96
|
discountList: goodPassList,
|
|
95
|
-
availableWalletIds
|
|
97
|
+
availableWalletIds,
|
|
98
|
+
virtualCurrencyList
|
|
96
99
|
};
|
|
97
100
|
}
|
|
101
|
+
normalizeVirtualCurrencyList(value) {
|
|
102
|
+
if (!Array.isArray(value)) return [];
|
|
103
|
+
return value.flatMap(item => {
|
|
104
|
+
const id = Number(item?.id);
|
|
105
|
+
const productId = Number(item?.product_id);
|
|
106
|
+
if (!Number.isFinite(id) || id <= 0 || !Number.isFinite(productId) || productId <= 0) {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
const displayExtension = Array.isArray(item?.extension_data) ? item.extension_data.find(extension => extension?.field_key === 'virtual_currency_display') : undefined;
|
|
110
|
+
let display = displayExtension?.value;
|
|
111
|
+
if (typeof display === 'string') {
|
|
112
|
+
try {
|
|
113
|
+
display = JSON.parse(display);
|
|
114
|
+
} catch {
|
|
115
|
+
display = {};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return [{
|
|
119
|
+
...item,
|
|
120
|
+
id,
|
|
121
|
+
product_id: productId,
|
|
122
|
+
balance: String(item?.balance ?? '0'),
|
|
123
|
+
virtual_currency_display: display && typeof display === 'object' && !Array.isArray(display) ? display : {}
|
|
124
|
+
}];
|
|
125
|
+
});
|
|
126
|
+
}
|
|
98
127
|
async batchSearch(code, options) {
|
|
99
128
|
const {
|
|
100
129
|
customerId,
|
|
@@ -71,6 +71,17 @@ export interface DiscountWithReason {
|
|
|
71
71
|
export interface DiscountPrepareConfigResult {
|
|
72
72
|
discountList: Discount[];
|
|
73
73
|
availableWalletIds: number[];
|
|
74
|
+
virtualCurrencyList?: VirtualCurrencyAsset[];
|
|
75
|
+
}
|
|
76
|
+
export interface VirtualCurrencyAsset extends Record<string, any> {
|
|
77
|
+
id: number;
|
|
78
|
+
product_id: number;
|
|
79
|
+
balance: string;
|
|
80
|
+
product_name?: string;
|
|
81
|
+
format_title?: Record<string, any>;
|
|
82
|
+
code?: string;
|
|
83
|
+
encoded?: string;
|
|
84
|
+
virtual_currency_display?: Record<string, any>;
|
|
74
85
|
}
|
|
75
86
|
interface ExtensionData {
|
|
76
87
|
id: number;
|