@pisell/pisellos 0.10.46 → 0.10.48
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/modules/Discount/types.d.ts +2 -0
- package/dist/modules/Rules/index.d.ts +2 -2
- package/dist/modules/Rules/index.js +129 -65
- package/dist/server/modules/order/types.d.ts +2 -0
- package/dist/server/utils/small-ticket.js +441 -64
- package/lib/model/strategy/adapter/promotion/index.js +46 -1
- package/lib/modules/Discount/types.d.ts +2 -0
- package/lib/modules/Rules/index.d.ts +2 -2
- package/lib/modules/Rules/index.js +71 -7
- package/lib/server/modules/order/types.d.ts +2 -0
- package/lib/server/utils/small-ticket.js +331 -51
- package/package.json +1 -1
|
@@ -1 +1,46 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "BUY_X_GET_Y_FREE_STRATEGY", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _examples.BUY_X_GET_Y_FREE_STRATEGY;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "ITEM_REWARD_STRATEGY", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _examples.ITEM_REWARD_STRATEGY;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "PromotionAdapter", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _adapter.PromotionAdapter;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "PromotionEvaluator", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _evaluator.PromotionEvaluator;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "X_ITEMS_FOR_Y_PRICE_STRATEGY", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _examples.X_ITEMS_FOR_Y_PRICE_STRATEGY;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "default", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _adapter.default;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
var _evaluator = require("./evaluator");
|
|
43
|
+
var _adapter = _interopRequireWildcard(require("./adapter"));
|
|
44
|
+
var _examples = require("./examples");
|
|
45
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
46
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
@@ -16,8 +16,8 @@ export declare class RulesModule extends BaseModule implements Module, RulesModu
|
|
|
16
16
|
getWalletPassEvaluator(): import("../..").WalletPassEvaluator | undefined;
|
|
17
17
|
private normalizeHolderRecordIds;
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
19
|
+
* 商品未开启 Holder 选择时跳过匹配;已开启时,特定 form Holder 卡
|
|
20
|
+
* 只适用于同一 Holder Record,是否必填不影响匹配规则。
|
|
21
21
|
*/
|
|
22
22
|
private checkHolderMatch;
|
|
23
23
|
isDiscountListAvailable({ oldDiscountList, newDiscountList, productList, orderTotalAmount, holders, isFormSubject, }: {
|
|
@@ -51,12 +51,20 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
54
|
+
* 商品未开启 Holder 选择时跳过匹配;已开启时,特定 form Holder 卡
|
|
55
|
+
* 只适用于同一 Holder Record,是否必填不影响匹配规则。
|
|
56
56
|
*/
|
|
57
|
-
checkHolderMatch(discount, product, holders) {
|
|
57
|
+
checkHolderMatch(discount, product, holderSource, holders) {
|
|
58
58
|
// 非表单类型 holder 视为匹配
|
|
59
59
|
if (discount.holder?.holder_type !== 'form') return true;
|
|
60
|
+
|
|
61
|
+
// getProduct 会裁剪商品字段,从原始商品读取配置,套餐子项沿用父商品。
|
|
62
|
+
const holderConfig = holderSource?.holder_config ?? holderSource?.metadata?.holder_config ?? holderSource?.origin?.holder_config ?? holderSource?.metadata?.origin?.holder_config ?? holderSource?._origin?.holder_config ?? holderSource?._extend?.holder_config ?? holderSource?._extend?.product?.holder_config ?? holderSource?._extend?.product?.metadata?.holder_config;
|
|
63
|
+
const holderStatus = holderConfig?.status;
|
|
64
|
+
const holderEnabled = holderStatus === true || ['enable', '1'].includes(String(holderStatus).trim().toLowerCase());
|
|
65
|
+
if (!holderEnabled || holderConfig?.resource_id === undefined || holderConfig?.resource_id === null || holderConfig?.resource_id === '') {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
60
68
|
const discountHolderIds = this.normalizeHolderRecordIds(discount.holder.holder_id);
|
|
61
69
|
if (!discountHolderIds.length) return false;
|
|
62
70
|
const productHolderIds = this.normalizeHolderRecordIds(product.holder_id);
|
|
@@ -914,7 +922,7 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
914
922
|
const isHolderMatch = this.checkHolderMatch(discount, {
|
|
915
923
|
isNeedHolder: resolveIsFormSubject(_tempVar) && !_tempVar?.isNormalProduct,
|
|
916
924
|
holder_id: _tempVar?.holder_id || product.holder_id
|
|
917
|
-
}, holders);
|
|
925
|
+
}, flatItem.originProduct, holders);
|
|
918
926
|
const timeReason = (0, _utils.getDiscountTimeUnavailableReason)(discount, (product?.startDate || (0, _dayjs.default)()).format('YYYY-MM-DD HH:mm:ss'));
|
|
919
927
|
const timeLimit = !timeReason;
|
|
920
928
|
// 是符合折扣的商品
|
|
@@ -1127,7 +1135,7 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
1127
1135
|
const isHolderMatch = this.checkHolderMatch(discount, {
|
|
1128
1136
|
isNeedHolder: resolveIsFormSubject(_tempVar) && !_tempVar?.isNormalProduct,
|
|
1129
1137
|
holder_id: _tempVar?.holder_id || product.holder_id
|
|
1130
|
-
}, holders);
|
|
1138
|
+
}, flatItem.originProduct, holders);
|
|
1131
1139
|
// 如果 holder 不匹配,则不适用
|
|
1132
1140
|
if (!isHolderMatch) return false;
|
|
1133
1141
|
let timeLimit = true;
|
|
@@ -2118,9 +2126,65 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
2118
2126
|
appliedProductDetails: committedAppliedProductDetails
|
|
2119
2127
|
};
|
|
2120
2128
|
});
|
|
2129
|
+
|
|
2130
|
+
// 整单分配完成后统一记录卡余额;历史使用已包含在服务端余额中,只扣本次新增次数。
|
|
2131
|
+
const entitlementBalances = new Map();
|
|
2132
|
+
addModeDiscount.forEach(discount => {
|
|
2133
|
+
const quota = (0, _entitlementPass.resolveEntitlementQuota)(discount);
|
|
2134
|
+
if (!quota) return;
|
|
2135
|
+
entitlementBalances.set(String(discount.id), quota.type === 'unlimited' ? null : Math.max(quota.balance - (entitlementUsageCounts.get(discount.id) || 0), 0));
|
|
2136
|
+
});
|
|
2137
|
+
const getEntitlementBalance = detail => {
|
|
2138
|
+
if (!(0, _entitlementPass.isEntitlementPass)(detail)) return undefined;
|
|
2139
|
+
const resourceId = detail?.discount?.resource_id ?? detail?.resource_id;
|
|
2140
|
+
return entitlementBalances.get(String(resourceId));
|
|
2141
|
+
};
|
|
2142
|
+
const needsEntitlementBalance = detail => {
|
|
2143
|
+
const balance = getEntitlementBalance(detail);
|
|
2144
|
+
return balance !== undefined && detail?.metadata?.balance !== balance;
|
|
2145
|
+
};
|
|
2146
|
+
const withEntitlementBalance = detail => {
|
|
2147
|
+
if (!needsEntitlementBalance(detail)) return detail;
|
|
2148
|
+
return {
|
|
2149
|
+
...detail,
|
|
2150
|
+
metadata: {
|
|
2151
|
+
...(detail.metadata || {}),
|
|
2152
|
+
balance: getEntitlementBalance(detail)
|
|
2153
|
+
}
|
|
2154
|
+
};
|
|
2155
|
+
};
|
|
2156
|
+
const getProductDiscountDetails = originProduct => {
|
|
2157
|
+
const product = this.hooks.getProduct(originProduct);
|
|
2158
|
+
return [...(product.discount_list || []), ...(product.bundle || []).flatMap(bundle => bundle.discount_list || [])];
|
|
2159
|
+
};
|
|
2160
|
+
const productsWithEntitlementBalances = entitlementBalances.size ? processedProductList.map(product => {
|
|
2161
|
+
if (!getProductDiscountDetails(product).some(needsEntitlementBalance)) {
|
|
2162
|
+
return product;
|
|
2163
|
+
}
|
|
2164
|
+
// 历史商品及套餐可能仍引用输入快照;仅复制有变化的行,并直接更新 metadata。
|
|
2165
|
+
// 不再次调用价格换算钩子,避免只补余额时改变商品价格。
|
|
2166
|
+
const nextProduct = (0, _lodashEs.cloneDeep)(product);
|
|
2167
|
+
getProductDiscountDetails(nextProduct).forEach(detail => {
|
|
2168
|
+
if (!needsEntitlementBalance(detail)) return;
|
|
2169
|
+
detail.metadata = withEntitlementBalance(detail).metadata;
|
|
2170
|
+
});
|
|
2171
|
+
return nextProduct;
|
|
2172
|
+
}) : processedProductList;
|
|
2173
|
+
const discountsWithEntitlementBalances = [...editModeDiscount, ...updatedDiscountList].map(discount => {
|
|
2174
|
+
if (!(0, _entitlementPass.isEntitlementPass)(discount) || !entitlementBalances.has(String(discount.id))) {
|
|
2175
|
+
return discount;
|
|
2176
|
+
}
|
|
2177
|
+
return {
|
|
2178
|
+
...discount,
|
|
2179
|
+
appliedProductDetails: (discount.appliedProductDetails || []).map(withEntitlementBalance),
|
|
2180
|
+
...(discount.committedAppliedProductDetails ? {
|
|
2181
|
+
committedAppliedProductDetails: discount.committedAppliedProductDetails.map(withEntitlementBalance)
|
|
2182
|
+
} : {})
|
|
2183
|
+
};
|
|
2184
|
+
});
|
|
2121
2185
|
return {
|
|
2122
|
-
productList:
|
|
2123
|
-
discountList:
|
|
2186
|
+
productList: productsWithEntitlementBalances,
|
|
2187
|
+
discountList: discountsWithEntitlementBalances
|
|
2124
2188
|
};
|
|
2125
2189
|
}
|
|
2126
2190
|
|
|
@@ -36,6 +36,8 @@ export type OrderSurchargeType = string;
|
|
|
36
36
|
export interface OrderProductDiscountMetadata {
|
|
37
37
|
/** 设备端本地唯一标识,用于与服务端记录对齐 */
|
|
38
38
|
unique_identification_number?: string;
|
|
39
|
+
/** 月卡扣除本单新增使用后的剩余次数;不限次数时为 null。 */
|
|
40
|
+
balance?: number | null;
|
|
39
41
|
[key: string]: unknown;
|
|
40
42
|
}
|
|
41
43
|
/**
|