@pisell/pisellos 2.2.77 → 2.2.79
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/core/index.d.ts +2 -2
- package/dist/model/strategy/adapter/walletPass/evaluator.js +2 -1
- package/dist/model/strategy/adapter/walletPass/locales.js +3 -0
- package/dist/model/strategy/adapter/walletPass/type.d.ts +4 -0
- package/dist/model/strategy/adapter/walletPass/utils.js +108 -9
- package/dist/modules/ProductList/index.d.ts +3 -0
- package/dist/modules/ProductList/index.js +9 -7
- package/dist/plugins/request.d.ts +2 -0
- package/dist/server/index.d.ts +27 -2
- package/dist/server/index.js +499 -295
- package/dist/server/modules/products/index.d.ts +101 -3
- package/dist/server/modules/products/index.js +1378 -242
- package/dist/server/modules/products/types.d.ts +24 -1
- package/dist/server/modules/products/types.js +3 -0
- package/dist/server/utils/product.d.ts +1 -0
- package/dist/server/utils/product.js +35 -25
- package/dist/solution/BookingTicket/index.d.ts +9 -1
- package/dist/solution/BookingTicket/index.js +41 -28
- package/dist/types/index.d.ts +3 -0
- package/lib/core/index.d.ts +2 -2
- package/lib/model/strategy/adapter/walletPass/evaluator.js +2 -1
- package/lib/model/strategy/adapter/walletPass/locales.js +3 -0
- package/lib/model/strategy/adapter/walletPass/type.d.ts +4 -0
- package/lib/model/strategy/adapter/walletPass/utils.js +68 -8
- package/lib/modules/ProductList/index.d.ts +3 -0
- package/lib/modules/ProductList/index.js +2 -2
- package/lib/plugins/request.d.ts +2 -0
- package/lib/server/index.d.ts +27 -2
- package/lib/server/index.js +172 -95
- package/lib/server/modules/products/index.d.ts +101 -3
- package/lib/server/modules/products/index.js +595 -52
- package/lib/server/modules/products/types.d.ts +24 -1
- package/lib/server/modules/products/types.js +1 -0
- package/lib/server/utils/product.d.ts +1 -0
- package/lib/server/utils/product.js +27 -11
- package/lib/solution/BookingTicket/index.d.ts +9 -1
- package/lib/solution/BookingTicket/index.js +10 -2
- package/lib/types/index.d.ts +3 -0
- package/package.json +1 -1
package/dist/core/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Plugin, PluginOptions, Module, ModuleOptions, PisellCore, PisellOSOptions, BusinessContext, ModuleContextConfig, InitializeServerOptions } from '../types';
|
|
1
|
+
import { Plugin, PluginOptions, Module, ModuleOptions, PisellCore, PisellOSOptions, BusinessContext, ModuleContextConfig, ServerOptions, InitializeServerOptions } from '../types';
|
|
2
2
|
import { EffectsManager } from '../effects';
|
|
3
3
|
/**
|
|
4
4
|
* pisell OS 核心实现
|
|
@@ -11,7 +11,7 @@ declare class PisellOSCore implements PisellCore {
|
|
|
11
11
|
private debug;
|
|
12
12
|
context: BusinessContext;
|
|
13
13
|
server: any;
|
|
14
|
-
|
|
14
|
+
serverOptions?: ServerOptions;
|
|
15
15
|
constructor(options?: PisellOSOptions);
|
|
16
16
|
private initialize;
|
|
17
17
|
/**
|
|
@@ -3,6 +3,7 @@ export var locales = {
|
|
|
3
3
|
'not_meet_the_required_conditions': '未达到使用条件',
|
|
4
4
|
'exceeds_the_maximum_deduction_limit': '超出最大抵扣金额限制',
|
|
5
5
|
'usage_limit_reached': '已达到使用次数上限',
|
|
6
|
+
'max_passes_per_item_reached': '该商品已达到卡券使用上限',
|
|
6
7
|
'not_available_for_this_channel': '当前渠道不可使用',
|
|
7
8
|
'not_valid_for_this_order_type': '当前订单类型不适用'
|
|
8
9
|
},
|
|
@@ -10,6 +11,7 @@ export var locales = {
|
|
|
10
11
|
'not_meet_the_required_conditions': 'Not meet the required conditions.',
|
|
11
12
|
'exceeds_the_maximum_deduction_limit': 'Exceeds the maximum deduction limit.',
|
|
12
13
|
'usage_limit_reached': 'Usage limit reached.',
|
|
14
|
+
'max_passes_per_item_reached': 'Max passes per item reached.',
|
|
13
15
|
'not_available_for_this_channel': 'Not available for this channel.',
|
|
14
16
|
'not_valid_for_this_order_type': 'Not valid for this order type.'
|
|
15
17
|
},
|
|
@@ -17,6 +19,7 @@ export var locales = {
|
|
|
17
19
|
'not_meet_the_required_conditions': '未達使用條件',
|
|
18
20
|
'exceeds_the_maximum_deduction_limit': '超出最大抵扣金額限制',
|
|
19
21
|
'usage_limit_reached': '已達使用次數上限',
|
|
22
|
+
'max_passes_per_item_reached': '該商品已達卡券使用上限',
|
|
20
23
|
'not_available_for_this_channel': '當前渠道不可使用',
|
|
21
24
|
'not_valid_for_this_order_type': '當前訂單類型不適用'
|
|
22
25
|
}
|
|
@@ -41,6 +41,8 @@ export interface Voucher {
|
|
|
41
41
|
allowCrossProduct: boolean;
|
|
42
42
|
/** 可用商品数量上限 (仅多商品) 默认为0,表示不限制商品数量。 */
|
|
43
43
|
applicableProductLimit: number;
|
|
44
|
+
/** 单商品可用卡券上限(同一 Wallet Pass 商品生成的卡券对同一商品行最多抵扣次数)。默认为 0,表示不限制。 */
|
|
45
|
+
maxPassesPerItem: number;
|
|
44
46
|
};
|
|
45
47
|
}
|
|
46
48
|
/**
|
|
@@ -127,6 +129,8 @@ export interface EvaluatorInput {
|
|
|
127
129
|
allowCrossProduct: boolean;
|
|
128
130
|
/** 可用商品数量上限 (仅多商品) 默认为0,表示不限制商品数量。 */
|
|
129
131
|
applicableProductLimit: number;
|
|
132
|
+
/** 单商品可用卡券上限(同一 Wallet Pass 商品生成的卡券对同一商品行最多抵扣次数)。默认为 0,表示不限制。 */
|
|
133
|
+
maxPassesPerItem: number;
|
|
130
134
|
}>[];
|
|
131
135
|
}
|
|
132
136
|
/**
|
|
@@ -118,8 +118,33 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
118
118
|
var productsCopy = expandProductsWithBundleItems(products, true);
|
|
119
119
|
var remainingOrderAmount = new Decimal(orderTotalAmount); // 订单剩余应付金额
|
|
120
120
|
|
|
121
|
+
// ========== 辅助工具:maxPassesPerItem(单商品可用卡券上限)追踪 ==========
|
|
122
|
+
// 获取指定 Wallet Pass 商品对指定订单商品行的已用卡券次数
|
|
123
|
+
var getItemPassUsage = function getItemPassUsage(usageMap, walletPassProductId, orderItemProductId) {
|
|
124
|
+
var _usageMap$get;
|
|
125
|
+
return ((_usageMap$get = usageMap.get(walletPassProductId)) === null || _usageMap$get === void 0 ? void 0 : _usageMap$get.get(orderItemProductId)) || 0;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// 更新指定 Wallet Pass 商品对指定订单商品行的已用卡券次数 +1
|
|
129
|
+
var incrementItemPassUsage = function incrementItemPassUsage(usageMap, walletPassProductId, orderItemProductId) {
|
|
130
|
+
if (!usageMap.has(walletPassProductId)) {
|
|
131
|
+
usageMap.set(walletPassProductId, new Map());
|
|
132
|
+
}
|
|
133
|
+
var innerMap = usageMap.get(walletPassProductId);
|
|
134
|
+
innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + 1);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// 按 maxPassesPerItem 过滤商品:排除已达到单商品可用卡券上限的商品
|
|
138
|
+
var filterByMaxPassesPerItem = function filterByMaxPassesPerItem(products, usageMap, walletPassProductId, maxPassesPerItem) {
|
|
139
|
+
if (maxPassesPerItem <= 0) return products; // 0 = 不限制
|
|
140
|
+
return products.filter(function (p) {
|
|
141
|
+
return getItemPassUsage(usageMap, walletPassProductId, p.product_id) < maxPassesPerItem;
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
// ================================================================
|
|
145
|
+
|
|
121
146
|
// 辅助函数:计算单张券的 _available_max_amount
|
|
122
|
-
var calculateAvailableMaxAmount = function calculateAvailableMaxAmount(voucher, productsData) {
|
|
147
|
+
var calculateAvailableMaxAmount = function calculateAvailableMaxAmount(voucher, productsData, itemPassUsage) {
|
|
123
148
|
var config = voucher.config;
|
|
124
149
|
var _ref2 = config !== null && config !== void 0 ? config : {},
|
|
125
150
|
_ref2$maxDeductionAmo = _ref2.maxDeductionAmount,
|
|
@@ -129,7 +154,9 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
129
154
|
_ref2$applicableProdu = _ref2.applicableProductLimit,
|
|
130
155
|
applicableProductLimit = _ref2$applicableProdu === void 0 ? 0 : _ref2$applicableProdu,
|
|
131
156
|
_ref2$deductTaxAndFee = _ref2.deductTaxAndFee,
|
|
132
|
-
deductTaxAndFee = _ref2$deductTaxAndFee === void 0 ? true : _ref2$deductTaxAndFee
|
|
157
|
+
deductTaxAndFee = _ref2$deductTaxAndFee === void 0 ? true : _ref2$deductTaxAndFee,
|
|
158
|
+
_ref2$maxPassesPerIte = _ref2.maxPassesPerItem,
|
|
159
|
+
maxPassesPerItem = _ref2$maxPassesPerIte === void 0 ? 0 : _ref2$maxPassesPerIte;
|
|
133
160
|
|
|
134
161
|
// 根据 deductTaxAndFee 配置获取推荐金额
|
|
135
162
|
var recommendedAmount = getRecommendedAmount(voucher);
|
|
@@ -145,6 +172,11 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
145
172
|
var applicableProducts = getApplicableProducts(voucher, productsData).filter(function (p) {
|
|
146
173
|
return p[amountField].greaterThan(0);
|
|
147
174
|
});
|
|
175
|
+
|
|
176
|
+
// 按 maxPassesPerItem 过滤:排除已达到单商品可用卡券上限的商品
|
|
177
|
+
if (itemPassUsage) {
|
|
178
|
+
applicableProducts = filterByMaxPassesPerItem(applicableProducts, itemPassUsage, voucher.product_id, maxPassesPerItem);
|
|
179
|
+
}
|
|
148
180
|
if (applicableProducts.length === 0) {
|
|
149
181
|
return new Decimal(0);
|
|
150
182
|
}
|
|
@@ -202,7 +234,7 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
202
234
|
};
|
|
203
235
|
|
|
204
236
|
// 辅助函数:判断券是否可用,返回可用性和原因代码
|
|
205
|
-
var isVoucherAvailable = function isVoucherAvailable(voucher, productsData, usedVoucherCounts) {
|
|
237
|
+
var isVoucherAvailable = function isVoucherAvailable(voucher, productsData, usedVoucherCounts, itemPassUsage) {
|
|
206
238
|
var config = voucher.config,
|
|
207
239
|
id = voucher.id,
|
|
208
240
|
product_id = voucher.product_id;
|
|
@@ -245,6 +277,25 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
245
277
|
};
|
|
246
278
|
}
|
|
247
279
|
}
|
|
280
|
+
|
|
281
|
+
// 检查 maxPassesPerItem:如果所有适用商品都已达到单商品可用卡券上限,则不可用
|
|
282
|
+
var maxPassesPerItem = (config === null || config === void 0 ? void 0 : config.maxPassesPerItem) || 0;
|
|
283
|
+
if (maxPassesPerItem > 0 && itemPassUsage) {
|
|
284
|
+
var _config$deductTaxAndF3;
|
|
285
|
+
var deductTaxAndFee = (_config$deductTaxAndF3 = config === null || config === void 0 ? void 0 : config.deductTaxAndFee) !== null && _config$deductTaxAndF3 !== void 0 ? _config$deductTaxAndF3 : true;
|
|
286
|
+
var amountField = deductTaxAndFee ? 'remainingAmountWithTax' : 'remainingAmountPure';
|
|
287
|
+
var availableAfterPassLimit = getApplicableProducts(voucher, productsData).filter(function (p) {
|
|
288
|
+
return p[amountField].greaterThan(0);
|
|
289
|
+
}).filter(function (p) {
|
|
290
|
+
return getItemPassUsage(itemPassUsage, product_id, p.product_id) < maxPassesPerItem;
|
|
291
|
+
});
|
|
292
|
+
if (availableAfterPassLimit.length === 0) {
|
|
293
|
+
return {
|
|
294
|
+
isAvailable: false,
|
|
295
|
+
reasonCode: 'max_passes_per_item_reached'
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
}
|
|
248
299
|
return {
|
|
249
300
|
isAvailable: true
|
|
250
301
|
};
|
|
@@ -272,6 +323,8 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
272
323
|
// 重置商品余额追踪(同时维护含税和不含税两个金额池)
|
|
273
324
|
var productsForRecommendation = expandProductsWithBundleItems(products, true);
|
|
274
325
|
remainingOrderAmount = new Decimal(orderTotalAmount);
|
|
326
|
+
// 追踪推荐阶段每个 Wallet Pass 商品对每个订单商品行的已使用卡券次数
|
|
327
|
+
var itemPassUsageMap = new Map();
|
|
275
328
|
|
|
276
329
|
/**
|
|
277
330
|
// 分类券:未跨商品券 vs 跨商品券
|
|
@@ -302,7 +355,7 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
302
355
|
// 处理单张券的抵扣
|
|
303
356
|
var applyVoucher = function applyVoucher(voucher) {
|
|
304
357
|
// 检查是否可用
|
|
305
|
-
var availabilityCheck = isVoucherAvailable(voucher, productsForRecommendation, usedVoucherCounts);
|
|
358
|
+
var availabilityCheck = isVoucherAvailable(voucher, productsForRecommendation, usedVoucherCounts, itemPassUsageMap);
|
|
306
359
|
if (!availabilityCheck.isAvailable) {
|
|
307
360
|
return false;
|
|
308
361
|
}
|
|
@@ -317,7 +370,9 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
317
370
|
_ref3$applicableProdu = _ref3.applicableProductLimit,
|
|
318
371
|
applicableProductLimit = _ref3$applicableProdu === void 0 ? 0 : _ref3$applicableProdu,
|
|
319
372
|
_ref3$deductTaxAndFee = _ref3.deductTaxAndFee,
|
|
320
|
-
deductTaxAndFee = _ref3$deductTaxAndFee === void 0 ? true : _ref3$deductTaxAndFee
|
|
373
|
+
deductTaxAndFee = _ref3$deductTaxAndFee === void 0 ? true : _ref3$deductTaxAndFee,
|
|
374
|
+
_ref3$maxPassesPerIte = _ref3.maxPassesPerItem,
|
|
375
|
+
maxPassesPerItem = _ref3$maxPassesPerIte === void 0 ? 0 : _ref3$maxPassesPerIte;
|
|
321
376
|
|
|
322
377
|
// 根据券的配置选择使用哪个单价字段和金额字段
|
|
323
378
|
var unitPriceField = deductTaxAndFee ? 'unitPriceWithTax' : 'unitPricePure';
|
|
@@ -327,6 +382,9 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
327
382
|
var applicableProducts = getApplicableProducts(voucher, productsForRecommendation).filter(function (p) {
|
|
328
383
|
return p[amountField].greaterThan(0);
|
|
329
384
|
});
|
|
385
|
+
|
|
386
|
+
// 按 maxPassesPerItem 过滤:排除已达到单商品可用卡券上限的商品
|
|
387
|
+
applicableProducts = filterByMaxPassesPerItem(applicableProducts, itemPassUsageMap, product_id, maxPassesPerItem);
|
|
330
388
|
if (applicableProducts.length === 0) return false;
|
|
331
389
|
|
|
332
390
|
// ========== 关键修改:在应用券之前,基于当前剩余金额计算 _available_max_amount ==========
|
|
@@ -466,6 +524,11 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
|
|
|
466
524
|
// 更新券使用次数(按 product_id 统计)
|
|
467
525
|
usedVoucherCounts.set(product_id, (usedVoucherCounts.get(product_id) || 0) + 1);
|
|
468
526
|
|
|
527
|
+
// 更新 maxPassesPerItem 追踪:记录每个被抵扣的商品行
|
|
528
|
+
deductionDetails.forEach(function (detail) {
|
|
529
|
+
incrementItemPassUsage(itemPassUsageMap, product_id, detail.product_id);
|
|
530
|
+
});
|
|
531
|
+
|
|
469
532
|
// 添加到推荐列表(包含基于当前剩余金额计算的 available_max_amount)
|
|
470
533
|
recommendedVouchers.push(_objectSpread(_objectSpread({}, voucher), {}, {
|
|
471
534
|
actualDeduction: totalDeducted.toNumber(),
|
|
@@ -547,6 +610,27 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
547
610
|
var remainingOrderAmount = new Decimal(orderTotalAmount);
|
|
548
611
|
var selectedWithDetails = [];
|
|
549
612
|
|
|
613
|
+
// 追踪每个 Wallet Pass 商品对每个订单商品行的已使用卡券次数
|
|
614
|
+
// Map<walletPassProductId, Map<orderItemProductId, usedCount>>
|
|
615
|
+
var itemPassUsageMap = new Map();
|
|
616
|
+
var getItemPassUsage = function getItemPassUsage(walletPassProductId, orderItemProductId) {
|
|
617
|
+
var _itemPassUsageMap$get;
|
|
618
|
+
return ((_itemPassUsageMap$get = itemPassUsageMap.get(walletPassProductId)) === null || _itemPassUsageMap$get === void 0 ? void 0 : _itemPassUsageMap$get.get(orderItemProductId)) || 0;
|
|
619
|
+
};
|
|
620
|
+
var incrementItemPassUsage = function incrementItemPassUsage(walletPassProductId, orderItemProductId) {
|
|
621
|
+
if (!itemPassUsageMap.has(walletPassProductId)) {
|
|
622
|
+
itemPassUsageMap.set(walletPassProductId, new Map());
|
|
623
|
+
}
|
|
624
|
+
var innerMap = itemPassUsageMap.get(walletPassProductId);
|
|
625
|
+
innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + 1);
|
|
626
|
+
};
|
|
627
|
+
var filterByMaxPassesPerItem = function filterByMaxPassesPerItem(products, walletPassProductId, maxPassesPerItem) {
|
|
628
|
+
if (maxPassesPerItem <= 0) return products; // 0 = 不限制
|
|
629
|
+
return products.filter(function (p) {
|
|
630
|
+
return getItemPassUsage(walletPassProductId, p.product_id) < maxPassesPerItem;
|
|
631
|
+
});
|
|
632
|
+
};
|
|
633
|
+
|
|
550
634
|
// 第一步:按顺序应用已选中的券,计算实际抵扣
|
|
551
635
|
selectedVouchers.forEach(function (selectedVoucher) {
|
|
552
636
|
var config = selectedVoucher.config,
|
|
@@ -554,8 +638,10 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
554
638
|
var maxDeductionAmount = config.maxDeductionAmount,
|
|
555
639
|
allowCrossProduct = config.allowCrossProduct,
|
|
556
640
|
applicableProductLimit = config.applicableProductLimit,
|
|
557
|
-
_config$
|
|
558
|
-
deductTaxAndFee = _config$
|
|
641
|
+
_config$deductTaxAndF4 = config.deductTaxAndFee,
|
|
642
|
+
deductTaxAndFee = _config$deductTaxAndF4 === void 0 ? true : _config$deductTaxAndF4,
|
|
643
|
+
_config$maxPassesPerI = config.maxPassesPerItem,
|
|
644
|
+
maxPassesPerItem = _config$maxPassesPerI === void 0 ? 0 : _config$maxPassesPerI;
|
|
559
645
|
|
|
560
646
|
// 根据券的配置选择使用哪个单价字段和金额字段
|
|
561
647
|
var unitPriceField = deductTaxAndFee ? 'unitPriceWithTax' : 'unitPricePure';
|
|
@@ -565,6 +651,9 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
565
651
|
var applicableProducts = getApplicableProducts(selectedVoucher, productsForCalc).filter(function (p) {
|
|
566
652
|
return p[amountField].greaterThan(0);
|
|
567
653
|
});
|
|
654
|
+
|
|
655
|
+
// 按 maxPassesPerItem 过滤:排除已达到单商品可用卡券上限的商品
|
|
656
|
+
applicableProducts = filterByMaxPassesPerItem(applicableProducts, selectedVoucher.product_id, maxPassesPerItem);
|
|
568
657
|
if (applicableProducts.length === 0) {
|
|
569
658
|
// 无适用商品,跳过
|
|
570
659
|
selectedWithDetails.push(_objectSpread(_objectSpread({}, selectedVoucher), {}, {
|
|
@@ -658,6 +747,11 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
658
747
|
|
|
659
748
|
// 更新订单剩余金额
|
|
660
749
|
remainingOrderAmount = remainingOrderAmount.minus(totalDeducted);
|
|
750
|
+
|
|
751
|
+
// 更新 maxPassesPerItem 追踪:记录每个被抵扣的商品行
|
|
752
|
+
deductionDetails.forEach(function (detail) {
|
|
753
|
+
incrementItemPassUsage(selectedVoucher.product_id, detail.product_id);
|
|
754
|
+
});
|
|
661
755
|
selectedWithDetails.push(_objectSpread(_objectSpread({}, selectedVoucher), {}, {
|
|
662
756
|
actualDeduction: totalDeducted.toNumber(),
|
|
663
757
|
// 转换为数字
|
|
@@ -692,8 +786,10 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
692
786
|
var maxDeductionAmount = config.maxDeductionAmount,
|
|
693
787
|
allowCrossProduct = config.allowCrossProduct,
|
|
694
788
|
applicableProductLimit = config.applicableProductLimit,
|
|
695
|
-
_config$
|
|
696
|
-
deductTaxAndFee = _config$
|
|
789
|
+
_config$deductTaxAndF5 = config.deductTaxAndFee,
|
|
790
|
+
deductTaxAndFee = _config$deductTaxAndF5 === void 0 ? true : _config$deductTaxAndF5,
|
|
791
|
+
_config$maxPassesPerI2 = config.maxPassesPerItem,
|
|
792
|
+
maxPassesPerItem = _config$maxPassesPerI2 === void 0 ? 0 : _config$maxPassesPerI2;
|
|
697
793
|
|
|
698
794
|
// 根据券的配置选择使用哪个单价字段和金额字段
|
|
699
795
|
var unitPriceField = deductTaxAndFee ? 'unitPriceWithTax' : 'unitPricePure';
|
|
@@ -726,6 +822,9 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
|
|
|
726
822
|
var applicableProducts = getApplicableProducts(voucher, productsForCalc).filter(function (p) {
|
|
727
823
|
return p[amountField].greaterThan(0);
|
|
728
824
|
});
|
|
825
|
+
|
|
826
|
+
// 按 maxPassesPerItem 过滤:排除已达到单商品可用卡券上限的商品
|
|
827
|
+
applicableProducts = filterByMaxPassesPerItem(applicableProducts, product_id, maxPassesPerItem);
|
|
729
828
|
if (applicableProducts.length === 0) {
|
|
730
829
|
isAvailable = false;
|
|
731
830
|
reasonCode = 'not_meet_the_required_conditions';
|
|
@@ -22,6 +22,9 @@ export declare class ProductList extends BaseModule implements Module {
|
|
|
22
22
|
schedule_datetime?: string;
|
|
23
23
|
with_count?: string[];
|
|
24
24
|
with_schedule?: number;
|
|
25
|
+
}, options?: {
|
|
26
|
+
callback?: (result: any) => void;
|
|
27
|
+
subscriberId?: string;
|
|
25
28
|
}): Promise<any>;
|
|
26
29
|
loadProductsPrice({ ids, customer_id, schedule_date, channel, }: {
|
|
27
30
|
ids?: number[];
|
|
@@ -84,7 +84,7 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
|
|
|
84
84
|
}, {
|
|
85
85
|
key: "loadProducts",
|
|
86
86
|
value: function () {
|
|
87
|
-
var _loadProducts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(_ref) {
|
|
87
|
+
var _loadProducts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(_ref, options) {
|
|
88
88
|
var _this$otherParams;
|
|
89
89
|
var _ref$category_ids, category_ids, _ref$product_ids, product_ids, _ref$collection, collection, _ref$menu_list_ids, menu_list_ids, paramsCustomerId, _ref$with_count, with_count, schedule_datetime, schedule_date, cacheId, with_schedule, userPlugin, customer_id, _userPlugin$get, productsData, sortedList;
|
|
90
90
|
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
@@ -134,7 +134,9 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
|
|
|
134
134
|
with_schedule: with_schedule,
|
|
135
135
|
schedule_datetime: schedule_datetime
|
|
136
136
|
}, {
|
|
137
|
-
osServer: true
|
|
137
|
+
osServer: true,
|
|
138
|
+
callback: options === null || options === void 0 ? void 0 : options.callback,
|
|
139
|
+
subscriberId: options === null || options === void 0 ? void 0 : options.subscriberId
|
|
138
140
|
});
|
|
139
141
|
case 6:
|
|
140
142
|
productsData = _context3.sent;
|
|
@@ -155,7 +157,7 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
|
|
|
155
157
|
}
|
|
156
158
|
}, _callee3, this);
|
|
157
159
|
}));
|
|
158
|
-
function loadProducts(_x5) {
|
|
160
|
+
function loadProducts(_x5, _x6) {
|
|
159
161
|
return _loadProducts.apply(this, arguments);
|
|
160
162
|
}
|
|
161
163
|
return loadProducts;
|
|
@@ -187,7 +189,7 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
|
|
|
187
189
|
}
|
|
188
190
|
}, _callee4, this);
|
|
189
191
|
}));
|
|
190
|
-
function loadProductsPrice(
|
|
192
|
+
function loadProductsPrice(_x7) {
|
|
191
193
|
return _loadProductsPrice.apply(this, arguments);
|
|
192
194
|
}
|
|
193
195
|
return loadProductsPrice;
|
|
@@ -235,7 +237,7 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
|
|
|
235
237
|
}
|
|
236
238
|
}, _callee6, this);
|
|
237
239
|
}));
|
|
238
|
-
function getProduct(
|
|
240
|
+
function getProduct(_x8) {
|
|
239
241
|
return _getProduct.apply(this, arguments);
|
|
240
242
|
}
|
|
241
243
|
return getProduct;
|
|
@@ -273,7 +275,7 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
|
|
|
273
275
|
}
|
|
274
276
|
}, _callee7, this);
|
|
275
277
|
}));
|
|
276
|
-
function addProduct(
|
|
278
|
+
function addProduct(_x9) {
|
|
277
279
|
return _addProduct.apply(this, arguments);
|
|
278
280
|
}
|
|
279
281
|
return addProduct;
|
|
@@ -292,7 +294,7 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
|
|
|
292
294
|
}
|
|
293
295
|
}, _callee8, this);
|
|
294
296
|
}));
|
|
295
|
-
function selectProducts(
|
|
297
|
+
function selectProducts(_x10) {
|
|
296
298
|
return _selectProducts.apply(this, arguments);
|
|
297
299
|
}
|
|
298
300
|
return selectProducts;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ declare class Server {
|
|
|
18
18
|
quotation?: QuotationModule;
|
|
19
19
|
schedule?: ScheduleModuleEx;
|
|
20
20
|
router: Router;
|
|
21
|
+
private productQuerySubscribers;
|
|
21
22
|
private moduleRegistry;
|
|
22
23
|
constructor(core: PisellCore);
|
|
23
24
|
/**
|
|
@@ -85,6 +86,12 @@ declare class Server {
|
|
|
85
86
|
* 获取所有已注册的模块列表
|
|
86
87
|
*/
|
|
87
88
|
getRegisteredModules(): string[];
|
|
89
|
+
/**
|
|
90
|
+
* 后台静默刷新商品数据
|
|
91
|
+
* 重新拉取全量 SSE 接口,更新本地数据后触发 onProductsSyncCompleted
|
|
92
|
+
* 不影响当前界面展示,适用于切回前台、定时刷新等场景
|
|
93
|
+
*/
|
|
94
|
+
refreshProductsInBackground(): Promise<void>;
|
|
88
95
|
/**
|
|
89
96
|
* 清空所有server模块的IndexedDB缓存
|
|
90
97
|
* @returns Promise<void>
|
|
@@ -132,10 +139,28 @@ declare class Server {
|
|
|
132
139
|
*/
|
|
133
140
|
private registerServerRoutes;
|
|
134
141
|
/**
|
|
135
|
-
*
|
|
136
|
-
|
|
142
|
+
* 根据 subscriberId 移除商品查询订阅者
|
|
143
|
+
*/
|
|
144
|
+
removeProductQuerySubscriber(subscriberId?: string): void;
|
|
145
|
+
/**
|
|
146
|
+
* 处理商品查询请求
|
|
147
|
+
* 存储订阅者信息,便于数据变更时推送最新结果
|
|
137
148
|
*/
|
|
138
149
|
private handleProductQuery;
|
|
150
|
+
/**
|
|
151
|
+
* 取消商品查询订阅(HTTP 路由入口)
|
|
152
|
+
*/
|
|
153
|
+
private handleUnsubscribeProductQuery;
|
|
154
|
+
/**
|
|
155
|
+
* 商品查询的核心计算逻辑(编排 Products、Menu、Schedule 模块)
|
|
156
|
+
* 供 handleProductQuery 首次返回及 pubsub 变更推送复用
|
|
157
|
+
*/
|
|
158
|
+
private computeProductQueryResult;
|
|
159
|
+
/**
|
|
160
|
+
* 数据变更后,遍历所有订阅者重新计算查询结果并通过 callback 推送
|
|
161
|
+
* 由 ProductsModule 的 onProductsSyncCompleted 事件触发
|
|
162
|
+
*/
|
|
163
|
+
private recomputeAndNotifyProductQuery;
|
|
139
164
|
/**
|
|
140
165
|
* 根据餐牌配置过滤商品
|
|
141
166
|
* @param products 所有商品列表
|