@pisell/pisellos 2.1.58 → 2.1.60
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/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/model/index.d.ts +1 -0
- package/dist/model/index.js +1 -0
- package/dist/model/strategy/adapter/index.d.ts +3 -0
- package/dist/model/strategy/adapter/index.js +4 -0
- package/dist/model/strategy/adapter/type.d.ts +28 -0
- package/dist/model/strategy/adapter/type.js +1 -0
- package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +84 -0
- package/dist/model/strategy/adapter/walletPass/evaluator.js +496 -0
- package/dist/model/strategy/adapter/walletPass/example.d.ts +4 -0
- package/dist/model/strategy/adapter/walletPass/example.js +258 -0
- package/dist/model/strategy/adapter/walletPass/index.d.ts +32 -0
- package/dist/model/strategy/adapter/walletPass/index.js +182 -0
- package/dist/model/strategy/adapter/walletPass/locales.d.ts +1 -0
- package/dist/model/strategy/adapter/walletPass/locales.js +23 -0
- package/dist/model/strategy/adapter/walletPass/type.d.ts +163 -0
- package/dist/model/strategy/adapter/walletPass/type.js +1 -0
- package/dist/model/strategy/adapter/walletPass/utils.d.ts +50 -0
- package/dist/model/strategy/adapter/walletPass/utils.js +965 -0
- package/dist/model/strategy/index.d.ts +94 -0
- package/dist/model/strategy/index.js +551 -0
- package/dist/model/strategy/strategy-example.d.ts +5 -0
- package/dist/model/strategy/strategy-example.js +331 -0
- package/dist/model/strategy/type.d.ts +228 -0
- package/dist/model/strategy/type.js +94 -0
- package/dist/modules/Cart/types.d.ts +2 -0
- package/dist/modules/Cart/utils/cartProduct.js +11 -0
- package/dist/modules/Discount/types.d.ts +17 -0
- package/dist/modules/Payment/index.d.ts +2 -1
- package/dist/modules/Payment/index.js +10 -7
- package/dist/modules/Payment/utils.js +3 -0
- package/dist/modules/Payment/walletpass.d.ts +23 -0
- package/dist/modules/Payment/walletpass.js +191 -95
- package/dist/modules/Product/index.d.ts +1 -1
- package/dist/modules/Rules/index.d.ts +8 -3
- package/dist/modules/Rules/index.js +152 -26
- package/dist/modules/Rules/types.d.ts +1 -0
- package/dist/modules/Summary/types.d.ts +2 -0
- package/dist/modules/Summary/utils.d.ts +6 -0
- package/dist/modules/Summary/utils.js +21 -0
- package/dist/plugins/window.d.ts +2 -0
- package/dist/solution/BookingByStep/index.d.ts +1 -0
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/dist/solution/Checkout/index.js +2 -0
- package/dist/solution/ShopDiscount/index.d.ts +1 -0
- package/dist/solution/ShopDiscount/index.js +11 -1
- package/dist/solution/ShopDiscount/types.d.ts +1 -0
- package/dist/solution/ShopDiscount/utils.js +43 -14
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -1
- package/lib/model/index.d.ts +1 -0
- package/lib/model/index.js +23 -0
- package/lib/model/strategy/adapter/index.d.ts +3 -0
- package/lib/model/strategy/adapter/index.js +45 -0
- package/lib/model/strategy/adapter/type.d.ts +28 -0
- package/lib/model/strategy/adapter/type.js +17 -0
- package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +84 -0
- package/lib/model/strategy/adapter/walletPass/evaluator.js +420 -0
- package/lib/model/strategy/adapter/walletPass/example.d.ts +4 -0
- package/lib/model/strategy/adapter/walletPass/example.js +207 -0
- package/lib/model/strategy/adapter/walletPass/index.d.ts +32 -0
- package/lib/model/strategy/adapter/walletPass/index.js +142 -0
- package/lib/model/strategy/adapter/walletPass/locales.d.ts +1 -0
- package/lib/model/strategy/adapter/walletPass/locales.js +51 -0
- package/lib/model/strategy/adapter/walletPass/type.d.ts +163 -0
- package/lib/model/strategy/adapter/walletPass/type.js +17 -0
- package/lib/model/strategy/adapter/walletPass/utils.d.ts +50 -0
- package/lib/model/strategy/adapter/walletPass/utils.js +660 -0
- package/lib/model/strategy/index.d.ts +94 -0
- package/lib/model/strategy/index.js +413 -0
- package/lib/model/strategy/strategy-example.d.ts +5 -0
- package/lib/model/strategy/strategy-example.js +318 -0
- package/lib/model/strategy/type.d.ts +228 -0
- package/lib/model/strategy/type.js +44 -0
- package/lib/modules/Cart/types.d.ts +2 -0
- package/lib/modules/Cart/utils/cartProduct.js +9 -0
- package/lib/modules/Discount/types.d.ts +17 -0
- package/lib/modules/Payment/index.d.ts +2 -1
- package/lib/modules/Payment/index.js +1 -0
- package/lib/modules/Payment/utils.js +3 -0
- package/lib/modules/Payment/walletpass.d.ts +23 -0
- package/lib/modules/Payment/walletpass.js +94 -17
- package/lib/modules/Product/index.d.ts +1 -1
- package/lib/modules/Rules/index.d.ts +8 -3
- package/lib/modules/Rules/index.js +370 -192
- package/lib/modules/Rules/types.d.ts +1 -0
- package/lib/modules/Summary/types.d.ts +2 -0
- package/lib/modules/Summary/utils.d.ts +6 -0
- package/lib/modules/Summary/utils.js +15 -0
- package/lib/plugins/window.d.ts +2 -0
- package/lib/solution/BookingByStep/index.d.ts +1 -0
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.js +0 -6
- package/lib/solution/Checkout/index.js +2 -0
- package/lib/solution/ShopDiscount/index.d.ts +1 -0
- package/lib/solution/ShopDiscount/index.js +6 -0
- package/lib/solution/ShopDiscount/types.d.ts +1 -0
- package/lib/solution/ShopDiscount/utils.js +22 -9
- package/package.json +1 -1
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WalletPass 评估器使用示例
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { WalletPassEvaluator } from "./evaluator";
|
|
6
|
+
|
|
7
|
+
// ============================================
|
|
8
|
+
// 准备测试数据
|
|
9
|
+
// ============================================
|
|
10
|
+
|
|
11
|
+
// 1. 商品列表
|
|
12
|
+
var products = [{
|
|
13
|
+
product_id: 60734,
|
|
14
|
+
price: 80,
|
|
15
|
+
quantity: 1,
|
|
16
|
+
name: '商品A'
|
|
17
|
+
}, {
|
|
18
|
+
product_id: 60735,
|
|
19
|
+
price: 50,
|
|
20
|
+
quantity: 2,
|
|
21
|
+
name: '商品B'
|
|
22
|
+
}];
|
|
23
|
+
|
|
24
|
+
// 订单总金额 = 80 + 50*2 = 180
|
|
25
|
+
|
|
26
|
+
// 2. Voucher 列表
|
|
27
|
+
var vouchers = [{
|
|
28
|
+
id: 'VOUCHER_001',
|
|
29
|
+
amount: 10,
|
|
30
|
+
balance: 10,
|
|
31
|
+
type: 'cash_voucher'
|
|
32
|
+
}, {
|
|
33
|
+
id: 'VOUCHER_002',
|
|
34
|
+
amount: 20,
|
|
35
|
+
balance: 20,
|
|
36
|
+
type: 'cash_voucher'
|
|
37
|
+
}, {
|
|
38
|
+
id: 'VOUCHER_003',
|
|
39
|
+
amount: 50,
|
|
40
|
+
balance: 50,
|
|
41
|
+
type: 'cash_voucher'
|
|
42
|
+
}];
|
|
43
|
+
|
|
44
|
+
// 3. 策略配置
|
|
45
|
+
var strategyConfigs = [
|
|
46
|
+
// 策略1: 满100减10,适用于 VOUCHER_001
|
|
47
|
+
{
|
|
48
|
+
metadata: {
|
|
49
|
+
id: 'STRATEGY_001',
|
|
50
|
+
name: '满100减10',
|
|
51
|
+
type: 'wallet_pass',
|
|
52
|
+
custom: {
|
|
53
|
+
maxDeductionAmount: 10,
|
|
54
|
+
// 最大抵扣10元
|
|
55
|
+
maxUsagePerOrder: 1,
|
|
56
|
+
// 每单最多用1张
|
|
57
|
+
deductTaxAndFee: true,
|
|
58
|
+
// 抵扣税费
|
|
59
|
+
applicableProductIds: [60734, 60735] // 适用于这两个商品
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
conditions: {
|
|
63
|
+
operator: 'and',
|
|
64
|
+
rules: [
|
|
65
|
+
// 匹配 voucher ID
|
|
66
|
+
{
|
|
67
|
+
type: 'operator',
|
|
68
|
+
field: 'voucherId',
|
|
69
|
+
operator: 'in',
|
|
70
|
+
value: ['VOUCHER_001']
|
|
71
|
+
},
|
|
72
|
+
// 适用商品总额需 >= 100
|
|
73
|
+
{
|
|
74
|
+
type: 'operator',
|
|
75
|
+
field: 'applicableProductTotal',
|
|
76
|
+
operator: '>=',
|
|
77
|
+
value: 100
|
|
78
|
+
}],
|
|
79
|
+
actionIds: ['deduct_10']
|
|
80
|
+
},
|
|
81
|
+
actions: [{
|
|
82
|
+
id: 'deduct_10',
|
|
83
|
+
type: 'DEDUCT_AMOUNT',
|
|
84
|
+
value: 10,
|
|
85
|
+
target: 'applicable_products',
|
|
86
|
+
priority: 1
|
|
87
|
+
}]
|
|
88
|
+
},
|
|
89
|
+
// 策略2: 满150减20,适用于 VOUCHER_002
|
|
90
|
+
{
|
|
91
|
+
metadata: {
|
|
92
|
+
id: 'STRATEGY_002',
|
|
93
|
+
name: '满150减20',
|
|
94
|
+
type: 'wallet_pass',
|
|
95
|
+
custom: {
|
|
96
|
+
maxDeductionAmount: 20,
|
|
97
|
+
maxUsagePerOrder: 1,
|
|
98
|
+
deductTaxAndFee: true,
|
|
99
|
+
applicableProductIds: [60734, 60735]
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
conditions: {
|
|
103
|
+
operator: 'and',
|
|
104
|
+
rules: [{
|
|
105
|
+
type: 'operator',
|
|
106
|
+
field: 'voucherId',
|
|
107
|
+
operator: 'in',
|
|
108
|
+
value: ['VOUCHER_002']
|
|
109
|
+
}, {
|
|
110
|
+
type: 'operator',
|
|
111
|
+
field: 'applicableProductTotal',
|
|
112
|
+
operator: '>=',
|
|
113
|
+
value: 150
|
|
114
|
+
}],
|
|
115
|
+
actionIds: ['deduct_20']
|
|
116
|
+
},
|
|
117
|
+
actions: [{
|
|
118
|
+
id: 'deduct_20',
|
|
119
|
+
type: 'DEDUCT_AMOUNT',
|
|
120
|
+
value: 20,
|
|
121
|
+
target: 'applicable_products',
|
|
122
|
+
priority: 1
|
|
123
|
+
}]
|
|
124
|
+
},
|
|
125
|
+
// 策略3: 满200减50,适用于 VOUCHER_003
|
|
126
|
+
{
|
|
127
|
+
metadata: {
|
|
128
|
+
id: 'STRATEGY_003',
|
|
129
|
+
name: '满200减50',
|
|
130
|
+
type: 'wallet_pass',
|
|
131
|
+
custom: {
|
|
132
|
+
maxDeductionAmount: 50,
|
|
133
|
+
maxUsagePerOrder: 2,
|
|
134
|
+
deductTaxAndFee: false,
|
|
135
|
+
applicableProductIds: [60734, 60735]
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
conditions: {
|
|
139
|
+
operator: 'and',
|
|
140
|
+
rules: [{
|
|
141
|
+
type: 'operator',
|
|
142
|
+
field: 'voucherId',
|
|
143
|
+
operator: 'in',
|
|
144
|
+
value: ['VOUCHER_003']
|
|
145
|
+
}, {
|
|
146
|
+
type: 'operator',
|
|
147
|
+
field: 'applicableProductTotal',
|
|
148
|
+
operator: '>=',
|
|
149
|
+
value: 200
|
|
150
|
+
}],
|
|
151
|
+
actionIds: ['deduct_50']
|
|
152
|
+
},
|
|
153
|
+
actions: [{
|
|
154
|
+
id: 'deduct_50',
|
|
155
|
+
type: 'DEDUCT_AMOUNT',
|
|
156
|
+
value: 50,
|
|
157
|
+
target: 'applicable_products',
|
|
158
|
+
priority: 1
|
|
159
|
+
}]
|
|
160
|
+
}];
|
|
161
|
+
|
|
162
|
+
// ============================================
|
|
163
|
+
// 执行评估
|
|
164
|
+
// ============================================
|
|
165
|
+
|
|
166
|
+
function runExample() {
|
|
167
|
+
console.log('========== WalletPass 评估器示例 ==========\n');
|
|
168
|
+
|
|
169
|
+
// 创建评估器实例
|
|
170
|
+
var evaluator = new WalletPassEvaluator();
|
|
171
|
+
|
|
172
|
+
// 执行评估
|
|
173
|
+
var results = evaluator.evaluate({
|
|
174
|
+
orderTotalAmount: 180,
|
|
175
|
+
products: products,
|
|
176
|
+
vouchers: vouchers,
|
|
177
|
+
strategyConfigs: strategyConfigs
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// 输出结果
|
|
181
|
+
console.log('订单信息:');
|
|
182
|
+
console.log("- \u603B\u91D1\u989D: ".concat(180, " \u5143"));
|
|
183
|
+
console.log("- \u5546\u54C1: ".concat(products.map(function (p) {
|
|
184
|
+
return "".concat(p.name, "(").concat(p.quantity, "\u4EF6)");
|
|
185
|
+
}).join(', '), "\n"));
|
|
186
|
+
console.log('评估结果:\n');
|
|
187
|
+
results.forEach(function (result, index) {
|
|
188
|
+
console.log("Voucher ".concat(index + 1, ": ").concat(result.voucher.id));
|
|
189
|
+
console.log(" \u9762\u989D: ".concat(result.voucher.amount, " \u5143"));
|
|
190
|
+
console.log(" \u53EF\u7528: ".concat(result.isApplicable ? '✅ 是' : '❌ 否'));
|
|
191
|
+
if (result.isApplicable) {
|
|
192
|
+
console.log(" \u6700\u5927\u62B5\u6263: ".concat(result.maxDeduction, " \u5143"));
|
|
193
|
+
console.log(" \u6BCF\u5355\u53EF\u7528: ".concat(result.canUseCount, " \u5F20"));
|
|
194
|
+
console.log(" \u62B5\u6263\u7A0E\u8D39: ".concat(result.deductTaxAndFee ? '是' : '否'));
|
|
195
|
+
console.log(" \u9002\u7528\u5546\u54C1: ".concat(result.applicableProductIds.join(', ')));
|
|
196
|
+
} else {
|
|
197
|
+
console.log(" \u539F\u56E0: ".concat(result.reason));
|
|
198
|
+
console.log(" \u539F\u56E0\u7801: ".concat(result.reasonCode));
|
|
199
|
+
}
|
|
200
|
+
console.log('');
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// 筛选可用的 vouchers
|
|
204
|
+
var availableVouchers = results.filter(function (r) {
|
|
205
|
+
return r.isApplicable;
|
|
206
|
+
});
|
|
207
|
+
console.log("\n\u5171 ".concat(availableVouchers.length, " \u5F20\u53EF\u7528"));
|
|
208
|
+
if (availableVouchers.length > 0) {
|
|
209
|
+
console.log('可用 voucher ID:');
|
|
210
|
+
availableVouchers.forEach(function (v) {
|
|
211
|
+
console.log(" - ".concat(v.voucher.id, ": \u6700\u591A\u62B5\u6263 ").concat(v.maxDeduction, " \u5143"));
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// 运行示例
|
|
217
|
+
runExample();
|
|
218
|
+
|
|
219
|
+
// ============================================
|
|
220
|
+
// 预期输出
|
|
221
|
+
// ============================================
|
|
222
|
+
/*
|
|
223
|
+
========== WalletPass 评估器示例 ==========
|
|
224
|
+
|
|
225
|
+
订单信息:
|
|
226
|
+
- 总金额: 180 元
|
|
227
|
+
- 商品: 商品A(1件), 商品B(2件)
|
|
228
|
+
|
|
229
|
+
评估结果:
|
|
230
|
+
|
|
231
|
+
Voucher 1: VOUCHER_001
|
|
232
|
+
面额: 10 元
|
|
233
|
+
可用: ✅ 是
|
|
234
|
+
最大抵扣: 10 元
|
|
235
|
+
每单可用: 1 张
|
|
236
|
+
抵扣税费: 是
|
|
237
|
+
适用商品: 60734, 60735
|
|
238
|
+
|
|
239
|
+
Voucher 2: VOUCHER_002
|
|
240
|
+
面额: 20 元
|
|
241
|
+
可用: ✅ 是
|
|
242
|
+
最大抵扣: 20 元
|
|
243
|
+
每单可用: 1 张
|
|
244
|
+
抵扣税费: 是
|
|
245
|
+
适用商品: 60734, 60735
|
|
246
|
+
|
|
247
|
+
Voucher 3: VOUCHER_003
|
|
248
|
+
面额: 50 元
|
|
249
|
+
可用: ❌ 否
|
|
250
|
+
原因: Conditions not met
|
|
251
|
+
原因码: CONDITION_NOT_MET
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
共 2 张可用
|
|
255
|
+
可用 voucher ID:
|
|
256
|
+
- VOUCHER_001: 最多抵扣 10 元
|
|
257
|
+
- VOUCHER_002: 最多抵扣 20 元
|
|
258
|
+
*/
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { EvaluationResult, RuntimeContext } from '../../type';
|
|
2
|
+
import { BusinessAdapter } from '../type';
|
|
3
|
+
import { WalletPassBusinessData, WalletPassTransformResult } from './type';
|
|
4
|
+
/**
|
|
5
|
+
* Wallet Pass 适配器
|
|
6
|
+
* 用于将 wallet pass 业务数据转换为策略引擎可识别的格式
|
|
7
|
+
*/
|
|
8
|
+
export default class WalletPassAdapter implements BusinessAdapter {
|
|
9
|
+
name: string;
|
|
10
|
+
version: string;
|
|
11
|
+
/**
|
|
12
|
+
* 准备运行时上下文
|
|
13
|
+
* 将业务数据转换为策略引擎可识别的 RuntimeContext
|
|
14
|
+
*/
|
|
15
|
+
prepareContext(businessData: WalletPassBusinessData): RuntimeContext;
|
|
16
|
+
/**
|
|
17
|
+
* 转换执行结果
|
|
18
|
+
* 将策略引擎的通用结果转换为业务层需要的格式
|
|
19
|
+
*/
|
|
20
|
+
transformResult(result: EvaluationResult, businessData?: WalletPassBusinessData): WalletPassTransformResult;
|
|
21
|
+
/**
|
|
22
|
+
* 格式化配置
|
|
23
|
+
*/
|
|
24
|
+
formatConfig(result: EvaluationResult, businessData?: WalletPassBusinessData): {
|
|
25
|
+
result: EvaluationResult;
|
|
26
|
+
businessData?: WalletPassBusinessData;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* 计算适用商品的总金额和数量
|
|
30
|
+
*/
|
|
31
|
+
private calculateApplicableProducts;
|
|
32
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
3
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
|
4
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
5
|
+
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; }
|
|
6
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
7
|
+
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); }
|
|
8
|
+
import { getApplicableProductIds, getMainProductPrice, getBundleItemPrice, getProductQuantity, getBundleItemIsOriginalPrice } from "./utils";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Wallet Pass 适配器
|
|
12
|
+
* 用于将 wallet pass 业务数据转换为策略引擎可识别的格式
|
|
13
|
+
*/
|
|
14
|
+
var WalletPassAdapter = /*#__PURE__*/function () {
|
|
15
|
+
function WalletPassAdapter() {
|
|
16
|
+
_classCallCheck(this, WalletPassAdapter);
|
|
17
|
+
_defineProperty(this, "name", 'WalletPassAdapter');
|
|
18
|
+
_defineProperty(this, "version", '1.0.0');
|
|
19
|
+
}
|
|
20
|
+
_createClass(WalletPassAdapter, [{
|
|
21
|
+
key: "prepareContext",
|
|
22
|
+
value:
|
|
23
|
+
/**
|
|
24
|
+
* 准备运行时上下文
|
|
25
|
+
* 将业务数据转换为策略引擎可识别的 RuntimeContext
|
|
26
|
+
*/
|
|
27
|
+
function prepareContext(businessData) {
|
|
28
|
+
var _strategyConfig$metad, _strategyConfig$metad2;
|
|
29
|
+
var orderTotalAmount = businessData.orderTotalAmount,
|
|
30
|
+
products = businessData.products,
|
|
31
|
+
voucher = businessData.voucher,
|
|
32
|
+
strategyConfig = businessData.strategyConfig;
|
|
33
|
+
|
|
34
|
+
// 提取订单中的商品ID
|
|
35
|
+
var productIds = products.map(function (p) {
|
|
36
|
+
return p.product_id;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// 从 voucher 中获取适用商品ID
|
|
40
|
+
var applicableProductIds = getApplicableProductIds(voucher);
|
|
41
|
+
|
|
42
|
+
// 获取 deductTaxAndFee 配置
|
|
43
|
+
var deductTaxAndFee = (_strategyConfig$metad = strategyConfig === null || strategyConfig === void 0 || (_strategyConfig$metad2 = strategyConfig.metadata) === null || _strategyConfig$metad2 === void 0 || (_strategyConfig$metad2 = _strategyConfig$metad2.custom) === null || _strategyConfig$metad2 === void 0 ? void 0 : _strategyConfig$metad2.deductTaxAndFee) !== null && _strategyConfig$metad !== void 0 ? _strategyConfig$metad : true;
|
|
44
|
+
|
|
45
|
+
// 计算适用商品的总金额和数量
|
|
46
|
+
var _this$calculateApplic = this.calculateApplicableProducts(products, applicableProductIds, deductTaxAndFee),
|
|
47
|
+
applicableTotal = _this$calculateApplic.applicableTotal,
|
|
48
|
+
applicableCount = _this$calculateApplic.applicableCount;
|
|
49
|
+
return {
|
|
50
|
+
entities: {
|
|
51
|
+
voucher: voucher,
|
|
52
|
+
products: products,
|
|
53
|
+
order: {
|
|
54
|
+
orderTotalAmount: orderTotalAmount,
|
|
55
|
+
products: products
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
attributes: {
|
|
59
|
+
// 订单消费金额
|
|
60
|
+
orderTotalAmount: orderTotalAmount,
|
|
61
|
+
// 适用商品金额
|
|
62
|
+
applicableProductTotalAmount: applicableTotal,
|
|
63
|
+
// 适用商品购买数量
|
|
64
|
+
applicableProductCount: applicableCount,
|
|
65
|
+
// 当前评估的 voucher ID
|
|
66
|
+
voucherProductId: voucher.product_id,
|
|
67
|
+
// 订单中的商品ID
|
|
68
|
+
productIds: productIds
|
|
69
|
+
},
|
|
70
|
+
metadata: {
|
|
71
|
+
timestamp: Date.now()
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 转换执行结果
|
|
78
|
+
* 将策略引擎的通用结果转换为业务层需要的格式
|
|
79
|
+
*/
|
|
80
|
+
}, {
|
|
81
|
+
key: "transformResult",
|
|
82
|
+
value: function transformResult(result, businessData) {
|
|
83
|
+
// 从策略配置中获取业务配置
|
|
84
|
+
var strategyConfig = businessData === null || businessData === void 0 ? void 0 : businessData.strategyConfig;
|
|
85
|
+
var businessConfig = (strategyConfig === null || strategyConfig === void 0 ? void 0 : strategyConfig.metadata.custom) || {};
|
|
86
|
+
|
|
87
|
+
// 从 voucher 中获取适用商品ID
|
|
88
|
+
var voucher = businessData === null || businessData === void 0 ? void 0 : businessData.voucher;
|
|
89
|
+
var applicableProductIds = voucher ? getApplicableProductIds(voucher) : null;
|
|
90
|
+
if (!result.applicable) {
|
|
91
|
+
return {
|
|
92
|
+
isApplicable: false,
|
|
93
|
+
canUseCount: 0,
|
|
94
|
+
maxDeduction: 0,
|
|
95
|
+
deductTaxAndFee: false,
|
|
96
|
+
applicableProductIds: [],
|
|
97
|
+
reason: result.message,
|
|
98
|
+
reasonCode: result.code,
|
|
99
|
+
strategyResult: result
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// 从配置中获取业务字段(不需要计算)
|
|
104
|
+
var maxDeduction = businessConfig.maxDeductionAmount || 0;
|
|
105
|
+
var canUseCount = businessConfig.maxUsagePerOrder || 0;
|
|
106
|
+
var deductTaxAndFee = businessConfig.deductTaxAndFee || false;
|
|
107
|
+
return {
|
|
108
|
+
isApplicable: true,
|
|
109
|
+
canUseCount: canUseCount,
|
|
110
|
+
maxDeduction: maxDeduction,
|
|
111
|
+
deductTaxAndFee: deductTaxAndFee,
|
|
112
|
+
applicableProductIds: applicableProductIds || [],
|
|
113
|
+
strategyResult: result
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* 格式化配置
|
|
119
|
+
*/
|
|
120
|
+
}, {
|
|
121
|
+
key: "formatConfig",
|
|
122
|
+
value: function formatConfig(result, businessData) {
|
|
123
|
+
return {
|
|
124
|
+
result: result,
|
|
125
|
+
businessData: businessData
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* 计算适用商品的总金额和数量
|
|
131
|
+
*/
|
|
132
|
+
}, {
|
|
133
|
+
key: "calculateApplicableProducts",
|
|
134
|
+
value: function calculateApplicableProducts(products, applicableProductIds) {
|
|
135
|
+
var deductTaxAndFee = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
136
|
+
var total = 0;
|
|
137
|
+
var count = 0;
|
|
138
|
+
|
|
139
|
+
// 如果为空数组,不适用任何商品
|
|
140
|
+
if (applicableProductIds !== null && applicableProductIds.length === 0) {
|
|
141
|
+
return {
|
|
142
|
+
applicableTotal: 0,
|
|
143
|
+
applicableCount: 0
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
products.forEach(function (product) {
|
|
147
|
+
var productQuantity = getProductQuantity(product);
|
|
148
|
+
|
|
149
|
+
// 检查主商品是否适用
|
|
150
|
+
var isMainProductApplicable = applicableProductIds === null || applicableProductIds.includes(product.product_id);
|
|
151
|
+
if (isMainProductApplicable) {
|
|
152
|
+
// 计算主商品价格(包含加减价子商品)
|
|
153
|
+
total += getMainProductPrice(product, deductTaxAndFee) * productQuantity;
|
|
154
|
+
count += productQuantity;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// 检查原价子商品(需要单独判断适用性)
|
|
158
|
+
if (product.product_bundle && product.product_bundle.length > 0) {
|
|
159
|
+
product.product_bundle.forEach(function (bundleItem) {
|
|
160
|
+
// 只处理原价子商品,加减价子商品已包含在主商品价格中
|
|
161
|
+
if (getBundleItemIsOriginalPrice(bundleItem)) {
|
|
162
|
+
// 检查子商品是否适用
|
|
163
|
+
var isBundleItemApplicable = applicableProductIds === null || applicableProductIds.includes(bundleItem.bundle_product_id);
|
|
164
|
+
if (isBundleItemApplicable) {
|
|
165
|
+
// 计算原价子商品价格
|
|
166
|
+
var bundleItemQuantity = bundleItem.num * productQuantity;
|
|
167
|
+
total += getBundleItemPrice(bundleItem, productQuantity, deductTaxAndFee);
|
|
168
|
+
count += bundleItemQuantity;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
return {
|
|
175
|
+
applicableTotal: total,
|
|
176
|
+
applicableCount: count
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
}]);
|
|
180
|
+
return WalletPassAdapter;
|
|
181
|
+
}();
|
|
182
|
+
export { WalletPassAdapter as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const locales: Record<string, Record<string, string>>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export var locales = {
|
|
2
|
+
'zh-CN': {
|
|
3
|
+
'not_meet_the_required_conditions': '未达到使用条件',
|
|
4
|
+
'exceeds_the_maximum_deduction_limit': '超出最大抵扣金额限制',
|
|
5
|
+
'usage_limit_reached': '已达到使用次数上限',
|
|
6
|
+
'not_available_for_this_channel': '当前渠道不可使用',
|
|
7
|
+
'not_valid_for_this_order_type': '当前订单类型不适用'
|
|
8
|
+
},
|
|
9
|
+
'en': {
|
|
10
|
+
'not_meet_the_required_conditions': 'Not meet the required conditions.',
|
|
11
|
+
'exceeds_the_maximum_deduction_limit': 'Exceeds the maximum deduction limit.',
|
|
12
|
+
'usage_limit_reached': 'Usage limit reached.',
|
|
13
|
+
'not_available_for_this_channel': 'Not available for this channel.',
|
|
14
|
+
'not_valid_for_this_order_type': 'Not valid for this order type.'
|
|
15
|
+
},
|
|
16
|
+
'zh-HK': {
|
|
17
|
+
'not_meet_the_required_conditions': '未達使用條件',
|
|
18
|
+
'exceeds_the_maximum_deduction_limit': '超出最大抵扣金額限制',
|
|
19
|
+
'usage_limit_reached': '已達使用次數上限',
|
|
20
|
+
'not_available_for_this_channel': '當前渠道不可使用',
|
|
21
|
+
'not_valid_for_this_order_type': '當前訂單類型不適用'
|
|
22
|
+
}
|
|
23
|
+
};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { EvaluationResult, StrategyConfig } from '../../type';
|
|
2
|
+
/**
|
|
3
|
+
* Voucher 数据结构
|
|
4
|
+
*/
|
|
5
|
+
export interface Voucher {
|
|
6
|
+
id: number;
|
|
7
|
+
amount: number;
|
|
8
|
+
balance: number;
|
|
9
|
+
type?: string;
|
|
10
|
+
usedCount?: number;
|
|
11
|
+
available_product_type?: 'product_all' | 'product_collection' | 'products';
|
|
12
|
+
available_product_ids?: number[];
|
|
13
|
+
product_id: number;
|
|
14
|
+
unified_available_status: number;
|
|
15
|
+
/** 用户手动编辑的金额,优先于 recommended_usage_amount 使用 */
|
|
16
|
+
edit_current_amount?: number;
|
|
17
|
+
/** 前端基于策略返回的 不可用状态 */
|
|
18
|
+
_unified_available_status?: number;
|
|
19
|
+
/** 前端基于策略返回的 可用最大金额 */
|
|
20
|
+
_available_max_amount?: number;
|
|
21
|
+
/** 前端基于策略返回的 不可用原因 */
|
|
22
|
+
reason?: string;
|
|
23
|
+
/** 前端基于策略返回的 不可用原因码 */
|
|
24
|
+
reasonCode?: string;
|
|
25
|
+
/** 后端计算推荐使用金额 */
|
|
26
|
+
recommended_usage_amount: number;
|
|
27
|
+
/** 后端计算推荐使用金额(仅商品) 不包含税费附加费 */
|
|
28
|
+
recommended_pure_product_usage_amount: number;
|
|
29
|
+
/** 实际抵扣金额 */
|
|
30
|
+
actualDeduction: number;
|
|
31
|
+
/** 抵扣详情 */
|
|
32
|
+
deductionDetails: any[];
|
|
33
|
+
config?: {
|
|
34
|
+
/** 最大抵扣金额 */
|
|
35
|
+
maxDeductionAmount: number;
|
|
36
|
+
/** 每单最多使用张数(同一 product_id 的券)。默认为 0,表示不限制数量。 */
|
|
37
|
+
maxUsagePerOrder: number;
|
|
38
|
+
/** 是否抵扣税费与附加费 */
|
|
39
|
+
deductTaxAndFee: boolean;
|
|
40
|
+
/** 适用粒度(多商品共用) 默认开启勾选项 */
|
|
41
|
+
allowCrossProduct: boolean;
|
|
42
|
+
/** 可用商品数量上限 (仅多商品) 默认为0,表示不限制商品数量。 */
|
|
43
|
+
applicableProductLimit: number;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 商品数据结构
|
|
48
|
+
*/
|
|
49
|
+
export interface Product {
|
|
50
|
+
product_id: number;
|
|
51
|
+
price: number;
|
|
52
|
+
quantity: number;
|
|
53
|
+
name?: string;
|
|
54
|
+
selling_price?: number;
|
|
55
|
+
/** 主商品折扣前金额,不包含套餐子商品 */
|
|
56
|
+
main_product_original_price?: number;
|
|
57
|
+
/** 主商品折扣后金额,不包含套餐子商品 */
|
|
58
|
+
main_product_selling_price?: number;
|
|
59
|
+
/** 主商品税费 */
|
|
60
|
+
tax_fee: number;
|
|
61
|
+
metadata: {
|
|
62
|
+
main_product_attached_bundle_tax_fee?: number;
|
|
63
|
+
main_product_attached_bundle_surcharge_fee?: number;
|
|
64
|
+
surcharge_rounding_remainder?: number;
|
|
65
|
+
main_product_selling_price: number;
|
|
66
|
+
};
|
|
67
|
+
is_price_include_tax: 0 | 1;
|
|
68
|
+
product_bundle: {
|
|
69
|
+
is_price_include_tax: 0 | 1;
|
|
70
|
+
bundle_id: number;
|
|
71
|
+
bundle_product_id: number;
|
|
72
|
+
bundle_variant_id: number;
|
|
73
|
+
price_type: string;
|
|
74
|
+
price_type_ext: string;
|
|
75
|
+
bundle_selling_price: number;
|
|
76
|
+
num: number;
|
|
77
|
+
is_charge_tax: number;
|
|
78
|
+
tax_fee: number;
|
|
79
|
+
metadata: {
|
|
80
|
+
surcharge_fee: number;
|
|
81
|
+
surcharge_rounding_remainder?: number;
|
|
82
|
+
};
|
|
83
|
+
}[];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Voucher 评估结果
|
|
87
|
+
*/
|
|
88
|
+
export interface VoucherEvaluationResult {
|
|
89
|
+
voucher: Voucher;
|
|
90
|
+
/** 是否可用 */
|
|
91
|
+
isApplicable: boolean;
|
|
92
|
+
/** 每单可使用张数 */
|
|
93
|
+
canUseCount: number;
|
|
94
|
+
/** 最大抵扣金额 */
|
|
95
|
+
maxDeduction: number;
|
|
96
|
+
/** 是否抵扣税费与附加费 */
|
|
97
|
+
deductTaxAndFee: boolean;
|
|
98
|
+
/** 适用商品ID列表 */
|
|
99
|
+
applicableProductIds: number[];
|
|
100
|
+
/** 不可用原因 */
|
|
101
|
+
reason?: string;
|
|
102
|
+
/** 不可用原因码 */
|
|
103
|
+
reasonCode?: string;
|
|
104
|
+
strategyResult?: EvaluationResult;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 评估器输入参数
|
|
108
|
+
*/
|
|
109
|
+
export interface EvaluatorInput {
|
|
110
|
+
/** 订单总金额 */
|
|
111
|
+
orderTotalAmount: number;
|
|
112
|
+
/** 商品列表 */
|
|
113
|
+
products: Product[];
|
|
114
|
+
/** 代金券列表 */
|
|
115
|
+
vouchers: Voucher[];
|
|
116
|
+
/** 策略配置列表 */
|
|
117
|
+
strategyConfigs?: StrategyConfig<{
|
|
118
|
+
/** 最大抵扣金额 */
|
|
119
|
+
maxDeductionAmount: number;
|
|
120
|
+
/** 每单最多使用张数(同一 product_id 的券)。默认为 0,表示不限制数量。 */
|
|
121
|
+
maxUsagePerOrder: number;
|
|
122
|
+
/** 是否抵扣税费与附加费 */
|
|
123
|
+
deductTaxAndFee: boolean;
|
|
124
|
+
/** 适用粒度(多商品共用) 默认开启勾选项 */
|
|
125
|
+
allowCrossProduct: boolean;
|
|
126
|
+
/** 可用商品数量上限 (仅多商品) 默认为0,表示不限制商品数量。 */
|
|
127
|
+
applicableProductLimit: number;
|
|
128
|
+
}>[];
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* WalletPassAdapter 业务数据输入
|
|
132
|
+
*/
|
|
133
|
+
export interface WalletPassBusinessData {
|
|
134
|
+
/** 订单总金额 */
|
|
135
|
+
orderTotalAmount: number;
|
|
136
|
+
/** 商品列表 */
|
|
137
|
+
products: Product[];
|
|
138
|
+
/** 当前评估的 voucher */
|
|
139
|
+
voucher: Voucher;
|
|
140
|
+
/** 策略配置 */
|
|
141
|
+
strategyConfig: StrategyConfig;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* WalletPassAdapter 转换结果
|
|
145
|
+
*/
|
|
146
|
+
export interface WalletPassTransformResult {
|
|
147
|
+
/** 是否可用 */
|
|
148
|
+
isApplicable: boolean;
|
|
149
|
+
/** 每单可使用张数 */
|
|
150
|
+
canUseCount: number;
|
|
151
|
+
/** 最大抵扣金额 */
|
|
152
|
+
maxDeduction: number;
|
|
153
|
+
/** 是否抵扣税费与附加费 */
|
|
154
|
+
deductTaxAndFee: boolean;
|
|
155
|
+
/** 适用商品ID列表 */
|
|
156
|
+
applicableProductIds: number[];
|
|
157
|
+
/** 不可用原因 */
|
|
158
|
+
reason?: string;
|
|
159
|
+
/** 不可用原因码 */
|
|
160
|
+
reasonCode?: string;
|
|
161
|
+
/** 原始策略评估结果 */
|
|
162
|
+
strategyResult?: EvaluationResult;
|
|
163
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|