@pisell/pisellos 2.2.265 → 2.2.270
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 -0
- package/dist/core/index.js +7 -0
- package/dist/model/strategy/adapter/promotion/adapter.d.ts +4 -0
- package/dist/model/strategy/adapter/promotion/adapter.js +23 -0
- package/dist/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
- package/dist/model/strategy/adapter/promotion/evaluator.js +279 -6
- package/dist/model/strategy/adapter/promotion/examples.d.ts +86 -0
- package/dist/model/strategy/adapter/promotion/examples.js +99 -0
- package/dist/model/strategy/adapter/promotion/index.d.ts +1 -1
- package/dist/model/strategy/adapter/promotion/index.js +1 -1
- package/dist/model/strategy/adapter/promotion/type.d.ts +90 -2
- package/dist/model/strategy/adapter/promotion/type.js +45 -0
- package/dist/modules/OpenData/index.d.ts +2 -0
- package/dist/modules/OpenData/index.js +8 -0
- package/dist/modules/Order/index.d.ts +1 -1
- package/dist/modules/Order/index.js +10 -3
- package/dist/modules/Order/utils.js +2 -1
- package/dist/modules/Rules/index.d.ts +1 -0
- package/dist/modules/Rules/index.js +34 -14
- package/dist/solution/BaseSales/index.d.ts +14 -1
- package/dist/solution/BaseSales/index.js +36 -12
- package/dist/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
- package/dist/solution/BaseSales/utils/cartPromotion.js +90 -31
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +3 -1
- package/dist/solution/BookingTicket/index.js +43 -31
- package/dist/solution/ScanOrder/index.js +31 -20
- package/dist/solution/VenueBooking/index.js +30 -19
- package/dist/types/index.d.ts +1 -0
- package/lib/core/index.d.ts +2 -0
- package/lib/core/index.js +4 -0
- package/lib/model/strategy/adapter/promotion/adapter.d.ts +4 -0
- package/lib/model/strategy/adapter/promotion/adapter.js +20 -0
- package/lib/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
- package/lib/model/strategy/adapter/promotion/evaluator.js +235 -0
- package/lib/model/strategy/adapter/promotion/examples.d.ts +86 -0
- package/lib/model/strategy/adapter/promotion/examples.js +91 -0
- package/lib/model/strategy/adapter/promotion/index.d.ts +1 -1
- package/lib/model/strategy/adapter/promotion/index.js +0 -49
- package/lib/model/strategy/adapter/promotion/type.d.ts +90 -2
- package/lib/model/strategy/adapter/promotion/type.js +2 -0
- package/lib/modules/OpenData/index.d.ts +2 -0
- package/lib/modules/OpenData/index.js +5 -0
- package/lib/modules/Order/index.d.ts +1 -1
- package/lib/modules/Order/index.js +9 -3
- package/lib/modules/Order/utils.js +6 -1
- package/lib/modules/Rules/index.d.ts +1 -0
- package/lib/modules/Rules/index.js +23 -4
- package/lib/solution/BaseSales/index.d.ts +14 -1
- package/lib/solution/BaseSales/index.js +22 -1
- package/lib/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
- package/lib/solution/BaseSales/utils/cartPromotion.js +63 -12
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +3 -1
- package/lib/solution/BookingTicket/index.js +11 -3
- package/lib/solution/ScanOrder/index.js +8 -0
- package/lib/solution/VenueBooking/index.js +8 -0
- package/lib/types/index.d.ts +1 -0
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { PromotionEvaluator } from './evaluator';
|
|
2
2
|
export { PromotionAdapter } from './adapter';
|
|
3
3
|
export { default } from './adapter';
|
|
4
|
-
export { X_ITEMS_FOR_Y_PRICE_STRATEGY, BUY_X_GET_Y_FREE_STRATEGY, } from './examples';
|
|
4
|
+
export { X_ITEMS_FOR_Y_PRICE_STRATEGY, BUY_X_GET_Y_FREE_STRATEGY, ITEM_REWARD_STRATEGY, } from './examples';
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
-
mod
|
|
26
|
-
));
|
|
27
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
-
|
|
29
|
-
// src/model/strategy/adapter/promotion/index.ts
|
|
30
|
-
var promotion_exports = {};
|
|
31
|
-
__export(promotion_exports, {
|
|
32
|
-
BUY_X_GET_Y_FREE_STRATEGY: () => import_examples.BUY_X_GET_Y_FREE_STRATEGY,
|
|
33
|
-
PromotionAdapter: () => import_adapter.PromotionAdapter,
|
|
34
|
-
PromotionEvaluator: () => import_evaluator.PromotionEvaluator,
|
|
35
|
-
X_ITEMS_FOR_Y_PRICE_STRATEGY: () => import_examples.X_ITEMS_FOR_Y_PRICE_STRATEGY,
|
|
36
|
-
default: () => import_adapter2.default
|
|
37
|
-
});
|
|
38
|
-
module.exports = __toCommonJS(promotion_exports);
|
|
39
|
-
var import_evaluator = require("./evaluator");
|
|
40
|
-
var import_adapter = require("./adapter");
|
|
41
|
-
var import_adapter2 = __toESM(require("./adapter"));
|
|
42
|
-
var import_examples = require("./examples");
|
|
43
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
44
|
-
0 && (module.exports = {
|
|
45
|
-
BUY_X_GET_Y_FREE_STRATEGY,
|
|
46
|
-
PromotionAdapter,
|
|
47
|
-
PromotionEvaluator,
|
|
48
|
-
X_ITEMS_FOR_Y_PRICE_STRATEGY
|
|
49
|
-
});
|
|
@@ -12,6 +12,8 @@ export declare const PROMOTION_ACTION_TYPES: {
|
|
|
12
12
|
readonly X_ITEMS_FOR_Y_PRICE: "X_ITEMS_FOR_Y_PRICE";
|
|
13
13
|
/** 买X送Y(买X件送Y件,可累计) */
|
|
14
14
|
readonly BUY_X_GET_Y_FREE: "BUY_X_GET_Y_FREE";
|
|
15
|
+
/** 商品奖励(满足条件后,订单内指定目标商品享优惠) */
|
|
16
|
+
readonly ITEM_REWARD: "ITEM_REWARD";
|
|
15
17
|
/** 固定折扣 */
|
|
16
18
|
readonly DISCOUNT_RATE: "DISCOUNT_RATE";
|
|
17
19
|
/** 固定减价 */
|
|
@@ -66,6 +68,59 @@ export interface BuyXGetYFreeConfig {
|
|
|
66
68
|
/** 可选的赠品列表 */
|
|
67
69
|
giftProducts?: ProductIdentifier[];
|
|
68
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* 商品奖励优惠方式
|
|
73
|
+
*
|
|
74
|
+
* - free: 目标商品最终价为 0
|
|
75
|
+
* - percent_off: 目标商品按百分比折扣,rewardValue 为 0-100
|
|
76
|
+
* - amount_off: 每个目标商品固定减免 rewardValue
|
|
77
|
+
* - fixed_price: 目标商品改为固定价 rewardValue
|
|
78
|
+
*/
|
|
79
|
+
export type ItemRewardMethod = 'free' | 'percent_off' | 'amount_off' | 'fixed_price';
|
|
80
|
+
/**
|
|
81
|
+
* 商品奖励数量规则
|
|
82
|
+
*
|
|
83
|
+
* - per_condition_quantity: 每满足 N 个条件商品,奖励 Y 个目标商品
|
|
84
|
+
* - all_targets: 满足条件后奖励全部目标商品
|
|
85
|
+
* - max_per_order: 满足条件后每单最多奖励固定数量目标商品
|
|
86
|
+
*/
|
|
87
|
+
export type ItemRewardQuantityRule = 'per_condition_quantity' | 'all_targets' | 'max_per_order';
|
|
88
|
+
/** 商品奖励目标选择规则 */
|
|
89
|
+
export type ItemRewardTargetSelection = 'consumer_best';
|
|
90
|
+
/**
|
|
91
|
+
* 商品奖励 - Action Value
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* value: {
|
|
95
|
+
* rewardMethod: 'free',
|
|
96
|
+
* quantityRule: 'per_condition_quantity',
|
|
97
|
+
* triggerQuantity: 1,
|
|
98
|
+
* rewardQuantity: 1,
|
|
99
|
+
* }
|
|
100
|
+
*/
|
|
101
|
+
export interface ItemRewardValue {
|
|
102
|
+
/** 奖励方式 */
|
|
103
|
+
rewardMethod: ItemRewardMethod;
|
|
104
|
+
/** 奖励值:percent_off/amount_off/fixed_price 使用,free 可省略 */
|
|
105
|
+
rewardValue?: number;
|
|
106
|
+
/** 奖励数量规则 */
|
|
107
|
+
quantityRule: ItemRewardQuantityRule;
|
|
108
|
+
/** 每满足 N 个条件商品;默认 1 */
|
|
109
|
+
triggerQuantity?: number;
|
|
110
|
+
/** 奖励 Y 个目标商品;默认 1 */
|
|
111
|
+
rewardQuantity?: number;
|
|
112
|
+
/** 每单最多奖励 Y 个目标商品;max_per_order 使用 */
|
|
113
|
+
maxRewardQuantity?: number;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* 商品奖励 - Action Config
|
|
117
|
+
*/
|
|
118
|
+
export interface ItemRewardConfig {
|
|
119
|
+
/** 奖励对象,本期支持指定商品/变体;product_variant_id=0 表示任意变体 */
|
|
120
|
+
rewardTargets?: ProductIdentifier[];
|
|
121
|
+
/** 目标商品超额时的选择规则;本期支持 consumer_best */
|
|
122
|
+
targetSelection?: ItemRewardTargetSelection;
|
|
123
|
+
}
|
|
69
124
|
/**
|
|
70
125
|
* 商品标识
|
|
71
126
|
*
|
|
@@ -102,10 +157,19 @@ export interface BuyXGetYFreeAction extends Omit<ActionEffect, 'type' | 'value'
|
|
|
102
157
|
valueType: 'object';
|
|
103
158
|
config?: BuyXGetYFreeConfig;
|
|
104
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* 商品奖励 Action
|
|
162
|
+
*/
|
|
163
|
+
export interface ItemRewardAction extends Omit<ActionEffect, 'type' | 'value' | 'config'> {
|
|
164
|
+
type: typeof PROMOTION_ACTION_TYPES.ITEM_REWARD;
|
|
165
|
+
value: ItemRewardValue;
|
|
166
|
+
valueType: 'object';
|
|
167
|
+
config?: ItemRewardConfig;
|
|
168
|
+
}
|
|
105
169
|
/**
|
|
106
170
|
* 促销活动 Action 联合类型
|
|
107
171
|
*/
|
|
108
|
-
export type PromotionAction = XItemsForYPriceAction | BuyXGetYFreeAction;
|
|
172
|
+
export type PromotionAction = XItemsForYPriceAction | BuyXGetYFreeAction | ItemRewardAction;
|
|
109
173
|
/**
|
|
110
174
|
* 促销相关运算符
|
|
111
175
|
*/
|
|
@@ -170,6 +234,8 @@ export interface PromotionProduct {
|
|
|
170
234
|
quantity: number;
|
|
171
235
|
/** 原价 */
|
|
172
236
|
original_price?: number;
|
|
237
|
+
/** 内部字段:编辑态订单行只允许参与 ITEM_REWARD,避免旧促销误算历史行 */
|
|
238
|
+
_promotionOnlyForItemReward?: boolean;
|
|
173
239
|
}
|
|
174
240
|
/**
|
|
175
241
|
* 促销活动适配器转换结果
|
|
@@ -195,7 +261,7 @@ export interface PromotionTransformResult {
|
|
|
195
261
|
/**
|
|
196
262
|
* Action 详情联合类型
|
|
197
263
|
*/
|
|
198
|
-
export type PromotionActionDetail = XItemsForYPriceActionDetail | BuyXGetYFreeActionDetail;
|
|
264
|
+
export type PromotionActionDetail = XItemsForYPriceActionDetail | BuyXGetYFreeActionDetail | ItemRewardActionDetail;
|
|
199
265
|
/**
|
|
200
266
|
* X件Y元 Action 详情
|
|
201
267
|
*/
|
|
@@ -226,6 +292,28 @@ export interface BuyXGetYFreeActionDetail {
|
|
|
226
292
|
/** 可选的赠品列表 */
|
|
227
293
|
giftProducts: ProductIdentifier[];
|
|
228
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* 商品奖励 Action 详情
|
|
297
|
+
*/
|
|
298
|
+
export interface ItemRewardActionDetail {
|
|
299
|
+
type: typeof PROMOTION_ACTION_TYPES.ITEM_REWARD;
|
|
300
|
+
/** 奖励方式 */
|
|
301
|
+
rewardMethod: ItemRewardMethod;
|
|
302
|
+
/** 奖励值:percent_off/amount_off/fixed_price 使用,free 为 0 */
|
|
303
|
+
rewardValue: number;
|
|
304
|
+
/** 奖励数量规则 */
|
|
305
|
+
quantityRule: ItemRewardQuantityRule;
|
|
306
|
+
/** 每满足 N 个条件商品;默认 1 */
|
|
307
|
+
triggerQuantity: number;
|
|
308
|
+
/** 奖励 Y 个目标商品;默认 1 */
|
|
309
|
+
rewardQuantity: number;
|
|
310
|
+
/** 每单最多奖励 Y 个目标商品;max_per_order 使用 */
|
|
311
|
+
maxRewardQuantity?: number;
|
|
312
|
+
/** 奖励对象,本期支持指定商品/变体 */
|
|
313
|
+
rewardTargets: ProductIdentifier[];
|
|
314
|
+
/** 目标商品超额时的选择规则 */
|
|
315
|
+
targetSelection: ItemRewardTargetSelection;
|
|
316
|
+
}
|
|
229
317
|
/**
|
|
230
318
|
* X件Y元 - 业务层计算结果
|
|
231
319
|
*
|
|
@@ -28,6 +28,8 @@ var PROMOTION_ACTION_TYPES = {
|
|
|
28
28
|
X_ITEMS_FOR_Y_PRICE: "X_ITEMS_FOR_Y_PRICE",
|
|
29
29
|
/** 买X送Y(买X件送Y件,可累计) */
|
|
30
30
|
BUY_X_GET_Y_FREE: "BUY_X_GET_Y_FREE",
|
|
31
|
+
/** 商品奖励(满足条件后,订单内指定目标商品享优惠) */
|
|
32
|
+
ITEM_REWARD: "ITEM_REWARD",
|
|
31
33
|
/** 固定折扣 */
|
|
32
34
|
DISCOUNT_RATE: "DISCOUNT_RATE",
|
|
33
35
|
/** 固定减价 */
|
|
@@ -27,6 +27,8 @@ export declare class OpenDataModule extends BaseModule implements Module {
|
|
|
27
27
|
fetchOpenData(params: OpenDataFetchParams): Promise<OpenDataConfig>;
|
|
28
28
|
getOpenData(): OpenDataConfig | null;
|
|
29
29
|
getLastFetchedAt(): number | null;
|
|
30
|
+
/** 清除内存与 sessionStorage 镜像中的 OpenData,供宿主切店时调用。 */
|
|
31
|
+
clearCache(): void;
|
|
30
32
|
checkAvailability(scheduleModule?: ScheduleModule): OpenDataAvailabilityResult;
|
|
31
33
|
storeChange(): void;
|
|
32
34
|
}
|
|
@@ -104,6 +104,11 @@ var OpenDataModule = class extends import_BaseModule.BaseModule {
|
|
|
104
104
|
getLastFetchedAt() {
|
|
105
105
|
return this.store.lastFetchedAt ?? null;
|
|
106
106
|
}
|
|
107
|
+
/** 清除内存与 sessionStorage 镜像中的 OpenData,供宿主切店时调用。 */
|
|
108
|
+
clearCache() {
|
|
109
|
+
this.store.data = null;
|
|
110
|
+
this.store.lastFetchedAt = null;
|
|
111
|
+
}
|
|
107
112
|
checkAvailability(scheduleModule) {
|
|
108
113
|
var _a;
|
|
109
114
|
const scheduleList = scheduleModule ? scheduleModule == null ? void 0 : scheduleModule.getScheduleListByIds(
|
|
@@ -485,7 +485,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
485
485
|
generateIdempotencyToken(): string;
|
|
486
486
|
syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
|
|
487
487
|
createOrder(params: CommitOrderParams['query']): {
|
|
488
|
-
type: "
|
|
488
|
+
type: "appointment_booking" | "virtual";
|
|
489
489
|
platform: string;
|
|
490
490
|
sales_channel: string;
|
|
491
491
|
order_sales_channel: string;
|
|
@@ -85,6 +85,11 @@ function isPaidPaymentRecord(payment) {
|
|
|
85
85
|
function isCommittedVoucherPaymentRecord(payment) {
|
|
86
86
|
return isVoucherPaymentRecord(payment) && (payment == null ? void 0 : payment.status) !== "voided" && (hasSyncedOrderPaymentRecord(payment) || isPaidPaymentRecord(payment));
|
|
87
87
|
}
|
|
88
|
+
function getVoucherPaymentLifecycleKey(payment) {
|
|
89
|
+
if (!isVoucherPaymentRecord(payment))
|
|
90
|
+
return null;
|
|
91
|
+
return `${String(payment.voucher_id)}::${String(payment.status || "")}`;
|
|
92
|
+
}
|
|
88
93
|
var OrderModule = class extends import_BaseModule.BaseModule {
|
|
89
94
|
constructor(name, version) {
|
|
90
95
|
super(name || "order", version);
|
|
@@ -2746,14 +2751,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
2746
2751
|
const committedVoucherPaymentIds = new Set(
|
|
2747
2752
|
committedVoucherPayments.filter((payment) => hasSyncedOrderPaymentRecord(payment)).map((payment) => String(payment.order_payment_id))
|
|
2748
2753
|
);
|
|
2749
|
-
const
|
|
2750
|
-
committedVoucherPayments.map((payment) =>
|
|
2754
|
+
const committedVoucherLifecycleKeys = new Set(
|
|
2755
|
+
committedVoucherPayments.map((payment) => getVoucherPaymentLifecycleKey(payment)).filter((key) => key !== null)
|
|
2751
2756
|
);
|
|
2752
2757
|
const replaceableVouchers = mappedVouchers.filter((payment) => {
|
|
2753
2758
|
if (hasSyncedOrderPaymentRecord(payment) && committedVoucherPaymentIds.has(String(payment.order_payment_id))) {
|
|
2754
2759
|
return false;
|
|
2755
2760
|
}
|
|
2756
|
-
|
|
2761
|
+
const lifecycleKey = getVoucherPaymentLifecycleKey(payment);
|
|
2762
|
+
if (lifecycleKey && committedVoucherLifecycleKeys.has(lifecycleKey)) {
|
|
2757
2763
|
return false;
|
|
2758
2764
|
}
|
|
2759
2765
|
return true;
|
|
@@ -444,7 +444,12 @@ function resolveEffectivePerUnitDiscount(product) {
|
|
|
444
444
|
(sum, discount) => sum + Number((discount == null ? void 0 : discount.amount) || 0),
|
|
445
445
|
0
|
|
446
446
|
);
|
|
447
|
-
const hasPromoDiscountItem = discountList.some(
|
|
447
|
+
const hasPromoDiscountItem = discountList.some(
|
|
448
|
+
(item) => {
|
|
449
|
+
var _a, _b;
|
|
450
|
+
return (item == null ? void 0 : item.type) === "promotion" || (item == null ? void 0 : item.type) === "product" && ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.source) === "promotion" && ((_b = item == null ? void 0 : item.metadata) == null ? void 0 : _b.actionType) === "ITEM_REWARD";
|
|
451
|
+
}
|
|
452
|
+
);
|
|
448
453
|
if (hasPromoDiscountItem)
|
|
449
454
|
return fromList;
|
|
450
455
|
const metadata = (product == null ? void 0 : product.metadata) || {};
|
|
@@ -35,6 +35,7 @@ export declare class RulesModule extends BaseModule implements Module, RulesModu
|
|
|
35
35
|
excludeDiscountListByType(discountList: Discount[], type: string): Discount[];
|
|
36
36
|
/** 手动改价场景:去掉 promotion,保留 type=product 等行内折扣 */
|
|
37
37
|
resolveDiscountListForManualOverride(discountList: Discount[]): Discount[];
|
|
38
|
+
private isItemRewardProductDiscount;
|
|
38
39
|
private getUnavailableReason;
|
|
39
40
|
calcDiscount({ discountList, productList, holders, isFormSubject, orderTotalAmount }: {
|
|
40
41
|
discountList: Discount[];
|
|
@@ -167,6 +167,16 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
167
167
|
resolveDiscountListForManualOverride(discountList) {
|
|
168
168
|
return this.excludeDiscountListByType(discountList, "promotion");
|
|
169
169
|
}
|
|
170
|
+
isItemRewardProductDiscount(product) {
|
|
171
|
+
var _a;
|
|
172
|
+
const discountList = Array.isArray(product == null ? void 0 : product.discount_list) ? product.discount_list : [];
|
|
173
|
+
return ((_a = product == null ? void 0 : product._promotion) == null ? void 0 : _a.actionType) === "ITEM_REWARD" && discountList.some(
|
|
174
|
+
(item) => {
|
|
175
|
+
var _a2, _b;
|
|
176
|
+
return (item == null ? void 0 : item.type) === "product" && ((_a2 = item == null ? void 0 : item.metadata) == null ? void 0 : _a2.source) === "promotion" && ((_b = item == null ? void 0 : item.metadata) == null ? void 0 : _b.actionType) === "ITEM_REWARD";
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
}
|
|
170
180
|
// 获取券不可用的原因
|
|
171
181
|
getUnavailableReason(discountList, productList) {
|
|
172
182
|
var _a;
|
|
@@ -500,6 +510,9 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
500
510
|
startDate: (_a2 = flatItem.parentProduct) == null ? void 0 : _a2.startDate
|
|
501
511
|
};
|
|
502
512
|
}
|
|
513
|
+
if (this.isItemRewardProductDiscount(product)) {
|
|
514
|
+
return false;
|
|
515
|
+
}
|
|
503
516
|
const isAvailableProduct = flatItem.type === "main" ? !((product == null ? void 0 : product.booking_id) && ((_b = product == null ? void 0 : product.discount_list) == null ? void 0 : _b.length) && ((_c = product == null ? void 0 : product.discount_list) == null ? void 0 : _c.every((d) => d.id && ["good_pass", "discount_card", "product_discount_card"].includes(d.tag || d.type)))) : !((flatItem == null ? void 0 : flatItem.booking_id) && !!((_e = (_d = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _d.discount_list) == null ? void 0 : _e.length) && ((_g = (_f = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _f.discount_list) == null ? void 0 : _g.every((d) => d.id)));
|
|
504
517
|
if (!isAvailableProduct) {
|
|
505
518
|
return false;
|
|
@@ -625,6 +638,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
625
638
|
};
|
|
626
639
|
originProduct = flatItem.originProduct;
|
|
627
640
|
}
|
|
641
|
+
const isItemRewardProductDiscount = this.isItemRewardProductDiscount(product);
|
|
628
642
|
addModeDiscount.forEach((discount) => {
|
|
629
643
|
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
630
644
|
const limitedData = discount == null ? void 0 : discount.limited_relation_product_data;
|
|
@@ -648,7 +662,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
648
662
|
].includes(discount2.tag || discount2.type)
|
|
649
663
|
))) : !((flatItem == null ? void 0 : flatItem.booking_id) && !!((_d = (_c = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _c.discount_list) == null ? void 0 : _d.length) && ((_f = (_e = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _e.discount_list) == null ? void 0 : _f.every((discount2) => discount2.id)));
|
|
650
664
|
const isBundleAvailable = this.checkPackageSubItemUsageRules(discount, flatItem);
|
|
651
|
-
if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable && ((_g = discount.config) == null ? void 0 : _g.isAvailable)) {
|
|
665
|
+
if (isAvailableProduct && !isItemRewardProductDiscount && isLimitedProduct && timeLimit && isBundleAvailable && ((_g = discount.config) == null ? void 0 : _g.isAvailable)) {
|
|
652
666
|
(_h = discountApplicability.get(discount.id)) == null ? void 0 : _h.push(product.id);
|
|
653
667
|
const applicableProducts = discountApplicableProducts.get(discount.id) || [];
|
|
654
668
|
const discountType = discount.tag || discount.type;
|
|
@@ -771,6 +785,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
771
785
|
}
|
|
772
786
|
const applicableDiscounts = sortedDiscountList.filter((discount) => {
|
|
773
787
|
var _a3, _b2, _c2, _d2;
|
|
788
|
+
if (this.isItemRewardProductDiscount(product))
|
|
789
|
+
return false;
|
|
774
790
|
const discountType = discount.tag || discount.type;
|
|
775
791
|
const currentOriginUid = getOriginProductUid(originProduct);
|
|
776
792
|
const isReapplyEditModeDiscountForProduct = discount.isEditMode && reapplyBookingDiscountProductUids.size > 0 && currentOriginUid && reapplyBookingDiscountProductUids.has(String(currentOriginUid)) && discount.isSelected === true;
|
|
@@ -845,6 +861,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
845
861
|
);
|
|
846
862
|
const selectedDiscount = selectedDiscountCard || applicableDiscounts[0];
|
|
847
863
|
let isManualDiscount = false;
|
|
864
|
+
let isItemRewardProductDiscount = false;
|
|
848
865
|
if (flatItem.type === "main") {
|
|
849
866
|
isManualDiscount = typeof product.isManualDiscount === "boolean" ? product.isManualDiscount : ((_g = product.discount_list) == null ? void 0 : _g.some((item) => item.type === "product")) || product.total != product.origin_total && (product.bundle || []).every(
|
|
850
867
|
(item) => {
|
|
@@ -855,7 +872,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
855
872
|
_i,
|
|
856
873
|
(item) => item.type === "product"
|
|
857
874
|
)));
|
|
858
|
-
|
|
875
|
+
isItemRewardProductDiscount = this.isItemRewardProductDiscount(product);
|
|
876
|
+
if (product.inPromotion && !isItemRewardProductDiscount) {
|
|
859
877
|
isManualDiscount = false;
|
|
860
878
|
}
|
|
861
879
|
} else {
|
|
@@ -969,7 +987,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
969
987
|
} else {
|
|
970
988
|
let total = product.inPromotion ? ((_w = product == null ? void 0 : product._promotion) == null ? void 0 : _w.finalPrice) ?? product.origin_total ?? product.total : product.origin_total ?? product.total;
|
|
971
989
|
let main_product_selling_price = product.price;
|
|
972
|
-
if ((product.discount_list || []).some((item) => item.type === "promotion") || (0, import_lodash_es.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
|
|
990
|
+
if ((product.discount_list || []).some((item) => item.type === "promotion") || isItemRewardProductDiscount || (0, import_lodash_es.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
|
|
973
991
|
total = product.total ?? product.origin_total;
|
|
974
992
|
main_product_selling_price = product.main_product_selling_price ?? main_product_selling_price;
|
|
975
993
|
}
|
|
@@ -977,7 +995,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
977
995
|
this.hooks.setProduct(originProduct, {
|
|
978
996
|
...isManualDiscount ? {
|
|
979
997
|
price: product.price,
|
|
980
|
-
main_product_selling_price: product.price
|
|
998
|
+
main_product_selling_price: isItemRewardProductDiscount ? main_product_selling_price : product.price,
|
|
999
|
+
...isItemRewardProductDiscount ? { total } : {}
|
|
981
1000
|
} : {
|
|
982
1001
|
_id: product._id.split("___")[0] + "___" + index,
|
|
983
1002
|
total,
|
|
@@ -48,6 +48,11 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
48
48
|
protected store: BaseSalesState;
|
|
49
49
|
protected otherParams: Record<string, any>;
|
|
50
50
|
protected cacheId: string | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* 由已在初始化阶段解析过设备短号的业务解决方案写入。
|
|
53
|
+
* 未设置时,支付编号仍按原逻辑实时读取设备信息。
|
|
54
|
+
*/
|
|
55
|
+
protected paymentNumberDevicePrefix: string | null;
|
|
51
56
|
/**
|
|
52
57
|
* window / request 暴露为 public:现存外部工具(如 BookingTicket Scan)通过
|
|
53
58
|
* `solution.window` / `solution.request` 直接访问插件,保持原有契约不破坏。
|
|
@@ -141,6 +146,11 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
141
146
|
*/
|
|
142
147
|
protected readSessionCacheData(): Record<string, any>;
|
|
143
148
|
protected getAppData<T>(key: string): T | undefined;
|
|
149
|
+
/**
|
|
150
|
+
* 复用业务解决方案初始化时已解析的支付设备短号。
|
|
151
|
+
* 空值会清除缓存,使后续支付恢复实时读取设备信息的兼容路径。
|
|
152
|
+
*/
|
|
153
|
+
protected setPaymentNumberDevicePrefix(prefix: unknown): void;
|
|
144
154
|
private getPaymentNumberDevicePrefixSync;
|
|
145
155
|
private getPaymentNumberDevicePrefixAsync;
|
|
146
156
|
private syncAppDataToTempOrder;
|
|
@@ -284,7 +294,10 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
284
294
|
* 同步兼容入口。无法等待 IoT 短号时,按调用当下的 device_id 或 LOCAL 生成。
|
|
285
295
|
*/
|
|
286
296
|
addOrderPayment(payment: OrderPaymentSource): OrderPaymentData[];
|
|
287
|
-
/**
|
|
297
|
+
/**
|
|
298
|
+
* 创建新支付项时优先使用业务解决方案初始化阶段缓存的设备短号;
|
|
299
|
+
* 未缓存的通用 BaseSales 保持实时读取设备信息的兼容语义。
|
|
300
|
+
*/
|
|
288
301
|
addOrderPaymentAsync(payment: OrderPaymentSource): Promise<OrderPaymentData[]>;
|
|
289
302
|
private addOrderPaymentWithDevicePrefix;
|
|
290
303
|
/** 更新当前订单中的指定支付项。 */
|
|
@@ -332,6 +332,11 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
332
332
|
order: void 0
|
|
333
333
|
};
|
|
334
334
|
this.otherParams = {};
|
|
335
|
+
/**
|
|
336
|
+
* 由已在初始化阶段解析过设备短号的业务解决方案写入。
|
|
337
|
+
* 未设置时,支付编号仍按原逻辑实时读取设备信息。
|
|
338
|
+
*/
|
|
339
|
+
this.paymentNumberDevicePrefix = null;
|
|
335
340
|
// 当前缓存中已加载的最新 SalesDetail;只读 getter 走它对外暴露详情数据。
|
|
336
341
|
this.currentSalesDetail = null;
|
|
337
342
|
this.discountConfigCacheKey = null;
|
|
@@ -862,6 +867,14 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
862
867
|
const coreData = (_f = (_d = (_c = app == null ? void 0 : app.models) == null ? void 0 : _c.getStore) == null ? void 0 : (_e = _d.call(_c)).getDataByModel) == null ? void 0 : _f.call(_e, "core", "core");
|
|
863
868
|
return coreData == null ? void 0 : coreData[key];
|
|
864
869
|
}
|
|
870
|
+
/**
|
|
871
|
+
* 复用业务解决方案初始化时已解析的支付设备短号。
|
|
872
|
+
* 空值会清除缓存,使后续支付恢复实时读取设备信息的兼容路径。
|
|
873
|
+
*/
|
|
874
|
+
setPaymentNumberDevicePrefix(prefix) {
|
|
875
|
+
const normalized = String(prefix ?? "").trim();
|
|
876
|
+
this.paymentNumberDevicePrefix = normalized || null;
|
|
877
|
+
}
|
|
865
878
|
getPaymentNumberDevicePrefixSync() {
|
|
866
879
|
if (!this.appPlugin)
|
|
867
880
|
return "LOCAL";
|
|
@@ -870,6 +883,9 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
870
883
|
getPaymentNumberDevicePrefixAsync() {
|
|
871
884
|
if (!this.appPlugin)
|
|
872
885
|
return Promise.resolve("LOCAL");
|
|
886
|
+
if (this.paymentNumberDevicePrefix) {
|
|
887
|
+
return Promise.resolve(this.paymentNumberDevicePrefix);
|
|
888
|
+
}
|
|
873
889
|
return (0, import_payment_number.resolvePaymentNumberDevicePrefix)((key) => this.getAppData(key));
|
|
874
890
|
}
|
|
875
891
|
syncAppDataToTempOrder(tempOrder) {
|
|
@@ -912,6 +928,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
912
928
|
var _a, _b;
|
|
913
929
|
this.core = core;
|
|
914
930
|
this.initializeOptions = options || {};
|
|
931
|
+
this.paymentNumberDevicePrefix = null;
|
|
915
932
|
this.otherParams = options.otherParams || {};
|
|
916
933
|
this.cacheId = (_a = this.otherParams) == null ? void 0 : _a.cacheId;
|
|
917
934
|
this.reusedSharedSubModuleNames.clear();
|
|
@@ -973,6 +990,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
973
990
|
}
|
|
974
991
|
});
|
|
975
992
|
this.currentSalesDetail = null;
|
|
993
|
+
this.paymentNumberDevicePrefix = null;
|
|
976
994
|
this.queuedServerOrderChanges = [];
|
|
977
995
|
this.salesDetailLoadSequence += 1;
|
|
978
996
|
await this.core.effects.emit(`${this.name}:onDestroy`, {});
|
|
@@ -2032,7 +2050,10 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
2032
2050
|
hasPaymentNumber ? "LOCAL" : this.getPaymentNumberDevicePrefixSync()
|
|
2033
2051
|
);
|
|
2034
2052
|
}
|
|
2035
|
-
/**
|
|
2053
|
+
/**
|
|
2054
|
+
* 创建新支付项时优先使用业务解决方案初始化阶段缓存的设备短号;
|
|
2055
|
+
* 未缓存的通用 BaseSales 保持实时读取设备信息的兼容语义。
|
|
2056
|
+
*/
|
|
2036
2057
|
async addOrderPaymentAsync(payment) {
|
|
2037
2058
|
const paymentRecord = payment;
|
|
2038
2059
|
const hasPaymentNumber = String(paymentRecord.payment_number || "").trim() !== "";
|
|
@@ -78,6 +78,7 @@ export interface CartPromotionEvaluator {
|
|
|
78
78
|
}>;
|
|
79
79
|
hasApplicableStrategy: boolean;
|
|
80
80
|
}>;
|
|
81
|
+
getStrategyConfigs?: () => unknown[];
|
|
81
82
|
}
|
|
82
83
|
/** 单个赠品减量项 */
|
|
83
84
|
export interface GiftReduceItem {
|
|
@@ -267,7 +268,8 @@ export declare function appendPromotionTags<T extends Record<string, any>>(produ
|
|
|
267
268
|
* 处理购物车的促销计算与赠品差异化。
|
|
268
269
|
*
|
|
269
270
|
* 流程:
|
|
270
|
-
* 1. 分离 main / gift / edit-product
|
|
271
|
+
* 1. 分离 main / gift / edit-product 三类(普通促销下带 `booking_id` 的编辑态商品不参与;
|
|
272
|
+
* 配置 ITEM_REWARD 时,编辑态商品也参与商品奖励重算)
|
|
271
273
|
* 2. 转 PromotionProduct 喂评估器 → 拿到 `evaluateCartWithPricing` 与 `getProductsApplicableStrategies`
|
|
272
274
|
* 3. 把 PricedProduct 映射回 OrderProduct 形态:
|
|
273
275
|
* - 参与促销的,写 `metadata._promotion` + 调整 `selling_price` / `main_product_selling_price`
|