@pisell/pisellos 2.2.152 → 2.2.154
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.js +1 -0
- package/dist/model/strategy/adapter/promotion/index.js +9 -0
- package/dist/modules/Cart/utils/cartProduct.js +1 -1
- package/dist/modules/Discount/index.d.ts +6 -2
- package/dist/modules/Discount/index.js +14 -8
- package/dist/modules/Order/index.d.ts +2 -0
- package/dist/modules/Order/index.js +234 -161
- package/dist/modules/Order/types.d.ts +19 -0
- package/dist/modules/Order/utils.js +7 -6
- package/dist/modules/Payment/index.d.ts +4 -0
- package/dist/modules/Payment/index.js +567 -505
- package/dist/modules/Payment/types.d.ts +29 -9
- package/dist/modules/SalesSummary/index.d.ts +7 -5
- package/dist/modules/SalesSummary/index.js +35 -11
- package/dist/plugins/app.d.ts +2 -0
- package/dist/server/index.d.ts +2 -5
- package/dist/server/index.js +58 -66
- package/dist/server/modules/index.d.ts +1 -1
- package/dist/server/modules/products/index.d.ts +12 -1
- package/dist/server/modules/products/index.js +169 -78
- package/dist/server/modules/products/types.d.ts +11 -0
- package/dist/server/modules/products/types.js +4 -0
- package/dist/server/utils/product.js +2 -2
- package/dist/solution/BaseSales/index.d.ts +26 -2
- package/dist/solution/BaseSales/index.js +342 -112
- package/dist/solution/BaseSales/types.d.ts +4 -4
- package/dist/solution/BaseSales/types.js +4 -4
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +62 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +116 -0
- package/dist/solution/BaseSales/utils.js +3 -3
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +11 -13
- package/dist/solution/BookingTicket/index.js +23 -37
- package/dist/solution/BookingTicket/types.d.ts +9 -6
- package/dist/solution/BookingTicket/types.js +6 -3
- package/dist/solution/BookingTicket/utils/cartView.d.ts +7 -12
- package/dist/solution/BookingTicket/utils/cartView.js +52 -14
- package/dist/solution/BookingTicket/utils/orderCustomer.d.ts +4 -0
- package/dist/solution/BookingTicket/utils/orderCustomer.js +31 -0
- package/dist/solution/Sales/index.d.ts +3 -0
- package/dist/solution/Sales/index.js +85 -43
- package/dist/solution/Sales/types.d.ts +3 -0
- package/dist/solution/ScanOrder/types.d.ts +4 -4
- package/dist/solution/ScanOrder/types.js +4 -4
- package/dist/solution/ScanOrder/utils.js +3 -3
- package/dist/solution/ShopDiscount/index.d.ts +2 -1
- package/dist/solution/ShopDiscount/index.js +32 -20
- package/dist/solution/ShopDiscount/types.d.ts +1 -0
- package/lib/core/index.js +1 -0
- package/lib/modules/Cart/utils/cartProduct.js +1 -1
- package/lib/modules/Discount/index.d.ts +6 -2
- package/lib/modules/Discount/index.js +3 -1
- package/lib/modules/Order/index.d.ts +2 -0
- package/lib/modules/Order/index.js +40 -8
- package/lib/modules/Order/types.d.ts +19 -0
- package/lib/modules/Order/utils.js +4 -2
- package/lib/modules/Payment/index.d.ts +4 -0
- package/lib/modules/Payment/index.js +26 -2
- package/lib/modules/Payment/types.d.ts +29 -9
- package/lib/modules/SalesSummary/index.d.ts +7 -5
- package/lib/modules/SalesSummary/index.js +29 -9
- package/lib/plugins/app.d.ts +2 -0
- package/lib/server/index.d.ts +2 -5
- package/lib/server/index.js +38 -58
- package/lib/server/modules/index.d.ts +1 -1
- package/lib/server/modules/products/index.d.ts +12 -1
- package/lib/server/modules/products/index.js +69 -9
- package/lib/server/modules/products/types.d.ts +11 -0
- package/lib/server/utils/product.js +2 -2
- package/lib/solution/BaseSales/index.d.ts +26 -2
- package/lib/solution/BaseSales/index.js +169 -3
- package/lib/solution/BaseSales/types.d.ts +4 -4
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +62 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +155 -0
- package/lib/solution/BaseSales/utils.js +3 -3
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +11 -13
- package/lib/solution/BookingTicket/index.js +17 -27
- package/lib/solution/BookingTicket/types.d.ts +9 -6
- package/lib/solution/BookingTicket/utils/cartView.d.ts +7 -12
- package/lib/solution/BookingTicket/utils/cartView.js +44 -18
- package/lib/solution/BookingTicket/utils/orderCustomer.d.ts +4 -0
- package/lib/solution/BookingTicket/utils/orderCustomer.js +58 -0
- package/lib/solution/Sales/index.d.ts +3 -0
- package/lib/solution/Sales/index.js +50 -15
- package/lib/solution/Sales/types.d.ts +3 -0
- package/lib/solution/ScanOrder/types.d.ts +4 -4
- package/lib/solution/ScanOrder/utils.js +3 -3
- package/lib/solution/ShopDiscount/index.d.ts +2 -1
- package/lib/solution/ShopDiscount/index.js +10 -4
- package/lib/solution/ShopDiscount/types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -76,7 +76,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
async initialize(core, options) {
|
|
79
|
-
var _a;
|
|
79
|
+
var _a, _b, _c;
|
|
80
80
|
this.core = core;
|
|
81
81
|
this.store = options.store;
|
|
82
82
|
if (!this.store.tempOrder) {
|
|
@@ -98,6 +98,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
98
98
|
this.cacheId = otherParams.cacheId;
|
|
99
99
|
this.salesSummaryModuleName = otherParams.salesSummaryModuleName;
|
|
100
100
|
this.rulesHooksOverride = (_a = otherParams.rules) == null ? void 0 : _a.hooks;
|
|
101
|
+
this.orderHooks = options.hooks || ((_b = otherParams.order) == null ? void 0 : _b.hooks) || ((_c = otherParams.hooks) == null ? void 0 : _c.order);
|
|
101
102
|
this.otherParams = otherParams;
|
|
102
103
|
this.registerDiscountModules(options);
|
|
103
104
|
this.restoreTempOrderFromStorage();
|
|
@@ -195,7 +196,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
195
196
|
}
|
|
196
197
|
async scanCode(code, customerId) {
|
|
197
198
|
var _a, _b, _c, _d, _e;
|
|
198
|
-
const resultDiscountList = await ((_a = this.store.discount) == null ? void 0 : _a.batchSearch(code, customerId)) || [];
|
|
199
|
+
const resultDiscountList = await ((_a = this.store.discount) == null ? void 0 : _a.batchSearch(code, { customerId })) || [];
|
|
199
200
|
const rulesModule = this.store.rules;
|
|
200
201
|
if (!rulesModule) {
|
|
201
202
|
return {
|
|
@@ -996,6 +997,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
996
997
|
this.persistTempOrder();
|
|
997
998
|
return tempOrder.payments;
|
|
998
999
|
}
|
|
1000
|
+
async shouldMergeProductToOrder(params) {
|
|
1001
|
+
var _a;
|
|
1002
|
+
const onBeforeMergeProductToOrder = (_a = this.orderHooks) == null ? void 0 : _a.onBeforeMergeProductToOrder;
|
|
1003
|
+
if (!onBeforeMergeProductToOrder)
|
|
1004
|
+
return true;
|
|
1005
|
+
const result = await onBeforeMergeProductToOrder({
|
|
1006
|
+
...params,
|
|
1007
|
+
defaultShouldMerge: true
|
|
1008
|
+
});
|
|
1009
|
+
if (typeof result === "boolean")
|
|
1010
|
+
return result;
|
|
1011
|
+
if (result && typeof result === "object" && typeof result.shouldMerge === "boolean") {
|
|
1012
|
+
return result.shouldMerge;
|
|
1013
|
+
}
|
|
1014
|
+
return true;
|
|
1015
|
+
}
|
|
999
1016
|
// ─── TempOrder: 商品 CRUD ───
|
|
1000
1017
|
async addProductToOrder(product, booking) {
|
|
1001
1018
|
var _a;
|
|
@@ -1018,13 +1035,28 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1018
1035
|
return false;
|
|
1019
1036
|
if (item.product_variant_id !== productToAdd.product_variant_id)
|
|
1020
1037
|
return false;
|
|
1021
|
-
const
|
|
1038
|
+
const existedFingerprint2 = (0, import_utils3.buildProductLineFingerprint)(
|
|
1022
1039
|
item.product_option_item,
|
|
1023
1040
|
item.product_bundle
|
|
1024
1041
|
);
|
|
1025
|
-
return
|
|
1042
|
+
return existedFingerprint2 === incomingFingerprint;
|
|
1026
1043
|
});
|
|
1027
|
-
|
|
1044
|
+
const matchedProduct = matchedIndex === -1 ? null : tempOrder.products[matchedIndex];
|
|
1045
|
+
const existedFingerprint = matchedProduct ? (0, import_utils3.buildProductLineFingerprint)(
|
|
1046
|
+
matchedProduct.product_option_item,
|
|
1047
|
+
matchedProduct.product_bundle
|
|
1048
|
+
) : "";
|
|
1049
|
+
const shouldMerge = matchedProduct ? await this.shouldMergeProductToOrder({
|
|
1050
|
+
incomingProduct: productToAdd,
|
|
1051
|
+
normalizedIncoming,
|
|
1052
|
+
matchedProduct,
|
|
1053
|
+
matchedIndex,
|
|
1054
|
+
incomingFingerprint,
|
|
1055
|
+
existedFingerprint,
|
|
1056
|
+
tempOrder,
|
|
1057
|
+
booking
|
|
1058
|
+
}) : false;
|
|
1059
|
+
if (matchedIndex === -1 || !matchedProduct || !shouldMerge) {
|
|
1028
1060
|
this.captureProductRuntime(
|
|
1029
1061
|
tempOrder,
|
|
1030
1062
|
productToAdd,
|
|
@@ -1039,7 +1071,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1039
1071
|
}
|
|
1040
1072
|
tempOrder.products.push(normalizedIncoming);
|
|
1041
1073
|
} else {
|
|
1042
|
-
const targetProduct =
|
|
1074
|
+
const targetProduct = matchedProduct;
|
|
1043
1075
|
const targetUid = (_a = targetProduct.metadata) == null ? void 0 : _a.unique_identification_number;
|
|
1044
1076
|
const normalizedProduct = (0, import_utils3.normalizeOrderProduct)({
|
|
1045
1077
|
...productToAdd,
|
|
@@ -1592,7 +1624,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1592
1624
|
// TODO 获取详情的接口
|
|
1593
1625
|
async getOrderInfoByRemote(order_id) {
|
|
1594
1626
|
const res = await this.request.get(`/order/sales/${order_id}`, {
|
|
1595
|
-
with: ["products", "
|
|
1627
|
+
with: ["products", "bookings", "payments", "customer", "summary", "contacts_info"]
|
|
1596
1628
|
});
|
|
1597
1629
|
if (res.code === 200) {
|
|
1598
1630
|
this.store.lastOrderInfo = res.data;
|
|
@@ -1716,7 +1748,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1716
1748
|
}
|
|
1717
1749
|
async getOrderInfo(order_id) {
|
|
1718
1750
|
const res = await this.request.get(`/order/sales/${order_id}`, {
|
|
1719
|
-
with: ["products", "
|
|
1751
|
+
with: ["products", "bookings"]
|
|
1720
1752
|
});
|
|
1721
1753
|
return res;
|
|
1722
1754
|
}
|
|
@@ -186,6 +186,25 @@ export interface UpdateProductInOrderParams {
|
|
|
186
186
|
product_bundle?: any[];
|
|
187
187
|
}
|
|
188
188
|
export type AddProductBookingInput = Record<string, any>;
|
|
189
|
+
export interface OrderProductMergeDecisionContext {
|
|
190
|
+
incomingProduct: Partial<OrderProduct> & OrderProductIdentity;
|
|
191
|
+
normalizedIncoming: OrderProduct;
|
|
192
|
+
matchedProduct: OrderProduct;
|
|
193
|
+
matchedIndex: number;
|
|
194
|
+
incomingFingerprint: string;
|
|
195
|
+
existedFingerprint: string;
|
|
196
|
+
tempOrder: OrderTempOrder;
|
|
197
|
+
booking?: AddProductBookingInput;
|
|
198
|
+
defaultShouldMerge: boolean;
|
|
199
|
+
}
|
|
200
|
+
export type OrderProductMergeDecisionResult = boolean | {
|
|
201
|
+
shouldMerge: boolean;
|
|
202
|
+
reason?: string;
|
|
203
|
+
[key: string]: any;
|
|
204
|
+
};
|
|
205
|
+
export interface OrderHooksConfig {
|
|
206
|
+
onBeforeMergeProductToOrder?: (context: OrderProductMergeDecisionContext) => OrderProductMergeDecisionResult | Promise<OrderProductMergeDecisionResult>;
|
|
207
|
+
}
|
|
189
208
|
/**
|
|
190
209
|
* 订单信息
|
|
191
210
|
*/
|
|
@@ -250,7 +250,7 @@ function formatSubmitOptionItems(options) {
|
|
|
250
250
|
return options.map((d) => {
|
|
251
251
|
const option = {
|
|
252
252
|
num: d == null ? void 0 : d.num,
|
|
253
|
-
option_group_item_id:
|
|
253
|
+
option_group_item_id: d == null ? void 0 : d.option_group_item_id,
|
|
254
254
|
option_group_id: d == null ? void 0 : d.option_group_id
|
|
255
255
|
};
|
|
256
256
|
const addPrice = (d == null ? void 0 : d.add_price) ?? (d == null ? void 0 : d.price);
|
|
@@ -525,7 +525,9 @@ function buildSubmitPayload(params) {
|
|
|
525
525
|
delivery_type: tempOrder.delivery_type || "nil",
|
|
526
526
|
schedule_date: scheduleDate,
|
|
527
527
|
created_at: tempOrder.created_at || formatDateTime(now),
|
|
528
|
-
bookings: (tempOrder.bookings || []).
|
|
528
|
+
bookings: (tempOrder.bookings || []).filter(
|
|
529
|
+
(booking) => Number(booking.parent_id ?? 0) !== 0
|
|
530
|
+
).map((booking) => normalizeSubmitBooking(booking)),
|
|
529
531
|
payments: tempOrder.payments || [],
|
|
530
532
|
// discount_list: tempOrder.discount_list || [],
|
|
531
533
|
relation_forms: tempOrder.relation_forms || [],
|
|
@@ -25,6 +25,9 @@ export declare class PaymentModule extends BaseModule implements Module, Payment
|
|
|
25
25
|
private dbManager;
|
|
26
26
|
private logger;
|
|
27
27
|
private voucherUpdateLockByOrderUuid;
|
|
28
|
+
private payMethodMemoryCache;
|
|
29
|
+
private payMethodListInFlight;
|
|
30
|
+
private isRefreshingPaymentMethods;
|
|
28
31
|
protected otherParams: any;
|
|
29
32
|
cash: CashPayment;
|
|
30
33
|
eftpos: EftposPayment;
|
|
@@ -59,6 +62,7 @@ export declare class PaymentModule extends BaseModule implements Module, Payment
|
|
|
59
62
|
* 获取支付方式列表
|
|
60
63
|
*/
|
|
61
64
|
getPayMethodListAsync(): Promise<PaymentMethod[]>;
|
|
65
|
+
private loadPayMethodListAsync;
|
|
62
66
|
/**
|
|
63
67
|
* 后台刷新支付方式列表
|
|
64
68
|
*/
|
|
@@ -76,6 +76,9 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
76
76
|
this.defaultVersion = "1.0.0";
|
|
77
77
|
// LoggerManager 实例
|
|
78
78
|
this.voucherUpdateLockByOrderUuid = /* @__PURE__ */ new Map();
|
|
79
|
+
this.payMethodMemoryCache = null;
|
|
80
|
+
this.payMethodListInFlight = null;
|
|
81
|
+
this.isRefreshingPaymentMethods = false;
|
|
79
82
|
this.otherParams = {};
|
|
80
83
|
this.cash = new import_cash.CashPaymentImpl(this);
|
|
81
84
|
this.eftpos = new import_eftpos.EftposPaymentImpl(this);
|
|
@@ -228,7 +231,20 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
228
231
|
* 获取支付方式列表
|
|
229
232
|
*/
|
|
230
233
|
async getPayMethodListAsync() {
|
|
234
|
+
var _a;
|
|
231
235
|
this.logInfo("Starting getPayMethodListAsync");
|
|
236
|
+
if ((_a = this.payMethodMemoryCache) == null ? void 0 : _a.length) {
|
|
237
|
+
return this.payMethodMemoryCache;
|
|
238
|
+
}
|
|
239
|
+
if (this.payMethodListInFlight) {
|
|
240
|
+
return this.payMethodListInFlight;
|
|
241
|
+
}
|
|
242
|
+
this.payMethodListInFlight = this.loadPayMethodListAsync().finally(() => {
|
|
243
|
+
this.payMethodListInFlight = null;
|
|
244
|
+
});
|
|
245
|
+
return this.payMethodListInFlight;
|
|
246
|
+
}
|
|
247
|
+
async loadPayMethodListAsync() {
|
|
232
248
|
try {
|
|
233
249
|
let cachedMethods = [];
|
|
234
250
|
try {
|
|
@@ -238,12 +254,14 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
238
254
|
}
|
|
239
255
|
const hasCache = cachedMethods.length > 0;
|
|
240
256
|
if (hasCache) {
|
|
257
|
+
this.payMethodMemoryCache = cachedMethods;
|
|
241
258
|
this.refreshPaymentMethodsInBackground(cachedMethods);
|
|
242
259
|
return cachedMethods;
|
|
243
260
|
}
|
|
244
261
|
const response = await this.request.get("/pay/custom-payment/all");
|
|
245
|
-
response.data = this.filterPayMethods(response.data);
|
|
262
|
+
response.data = await this.filterPayMethods(response.data);
|
|
246
263
|
const payMethods = response.data || [];
|
|
264
|
+
this.payMethodMemoryCache = payMethods;
|
|
247
265
|
try {
|
|
248
266
|
for (const method of payMethods) {
|
|
249
267
|
await this.dbManager.update("pay_method", method);
|
|
@@ -269,14 +287,18 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
269
287
|
* 后台刷新支付方式列表
|
|
270
288
|
*/
|
|
271
289
|
async refreshPaymentMethodsInBackground(cachedMethods) {
|
|
290
|
+
if (this.isRefreshingPaymentMethods)
|
|
291
|
+
return;
|
|
292
|
+
this.isRefreshingPaymentMethods = true;
|
|
272
293
|
this.logInfo("Starting refreshPaymentMethodsInBackground", {
|
|
273
294
|
cachedMethodsCount: cachedMethods.length
|
|
274
295
|
});
|
|
275
296
|
try {
|
|
276
297
|
console.log("[PaymentModule] 后台刷新支付方式列表...");
|
|
277
298
|
const response = await this.request.get("/pay/custom-payment/all");
|
|
278
|
-
response.data = this.filterPayMethods(response.data);
|
|
299
|
+
response.data = await this.filterPayMethods(response.data);
|
|
279
300
|
const newPayMethods = response.data || [];
|
|
301
|
+
this.payMethodMemoryCache = newPayMethods;
|
|
280
302
|
const hasChanges = this.hasPaymentMethodsChanged(
|
|
281
303
|
cachedMethods,
|
|
282
304
|
newPayMethods
|
|
@@ -310,6 +332,8 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
310
332
|
}
|
|
311
333
|
} catch (error) {
|
|
312
334
|
console.error("[PaymentModule] 后台刷新支付方式失败", error);
|
|
335
|
+
} finally {
|
|
336
|
+
this.isRefreshingPaymentMethods = false;
|
|
313
337
|
}
|
|
314
338
|
}
|
|
315
339
|
/**
|
|
@@ -349,6 +349,18 @@ export interface EftposPayment {
|
|
|
349
349
|
/**
|
|
350
350
|
* 钱包支付接口
|
|
351
351
|
*/
|
|
352
|
+
export interface WalletInitializationResult {
|
|
353
|
+
walletRecommendList: WalletRecommendItem[];
|
|
354
|
+
userIdentificationCodes: UserIdentificationCodeItem[];
|
|
355
|
+
transformList: any[];
|
|
356
|
+
noApplicableVoucher: any[];
|
|
357
|
+
products: any[];
|
|
358
|
+
}
|
|
359
|
+
export interface WalletStoredInitData {
|
|
360
|
+
transformList: any[];
|
|
361
|
+
noApplicableVoucher: any[];
|
|
362
|
+
products: any[];
|
|
363
|
+
}
|
|
352
364
|
export interface WalletPassPayment {
|
|
353
365
|
/** 生成钱包API默认参数 */
|
|
354
366
|
generateWalletParams: (businessData: WalletInitBusinessData) => WalletDeductionRecommendParams;
|
|
@@ -357,21 +369,25 @@ export interface WalletPassPayment {
|
|
|
357
369
|
/** 清理已存储的钱包参数 */
|
|
358
370
|
clearStoredWalletParams: () => void;
|
|
359
371
|
/** 初始化钱包数据(从业务数据开始,内部生成参数) */
|
|
360
|
-
initializeWalletDataFromBusinessAsync: (businessData: WalletInitBusinessData) => Promise<
|
|
361
|
-
walletRecommendList: WalletRecommendItem[];
|
|
362
|
-
userIdentificationCodes: UserIdentificationCodeItem[];
|
|
363
|
-
}>;
|
|
372
|
+
initializeWalletDataFromBusinessAsync: (businessData: WalletInitBusinessData) => Promise<WalletInitializationResult>;
|
|
364
373
|
/** 初始化钱包数据(先获取推荐列表,再获取用户识别码列表) */
|
|
365
|
-
initializeWalletDataAsync: (baseParams: WalletDeductionRecommendParams) => Promise<
|
|
366
|
-
walletRecommendList: WalletRecommendItem[];
|
|
367
|
-
userIdentificationCodes: UserIdentificationCodeItem[];
|
|
368
|
-
}>;
|
|
374
|
+
initializeWalletDataAsync: (baseParams: WalletDeductionRecommendParams) => Promise<WalletInitializationResult>;
|
|
369
375
|
/** 获取钱包推荐扣款列表(异步获取并缓存) */
|
|
370
376
|
getWalletPassRecommendListAsync: (params: WalletDeductionRecommendParams) => Promise<WalletRecommendItem[]>;
|
|
371
377
|
/** 查询用户识别码列表(异步获取并缓存) */
|
|
372
378
|
getUserIdentificationCodeListAsync: (params: UserIdentificationCodeParams) => Promise<UserIdentificationCodeItem[]>;
|
|
373
379
|
/** 搜索识别码信息 */
|
|
374
|
-
searchIdentificationCodeAsync: (params: SearchIdentificationCodeParams
|
|
380
|
+
searchIdentificationCodeAsync: (params: SearchIdentificationCodeParams, config?: {
|
|
381
|
+
noCache?: boolean;
|
|
382
|
+
}) => Promise<SearchIdentificationCodeResult>;
|
|
383
|
+
/** 将推荐钱包列表转换为 prepare_payments */
|
|
384
|
+
formatWalletPassList2PreparePayments: (list: WalletRecommendItem[]) => {
|
|
385
|
+
voucher_id: number;
|
|
386
|
+
amount: number;
|
|
387
|
+
tag: string;
|
|
388
|
+
wallet_pass_usage_unit?: unknown;
|
|
389
|
+
wallet_pass_use_value?: string | number | null;
|
|
390
|
+
}[];
|
|
375
391
|
/** 获取缓存的搜索结果列表 */
|
|
376
392
|
getSearchResults: () => SearchIdentificationCodeItem[];
|
|
377
393
|
/** 根据识别码查找搜索结果 */
|
|
@@ -384,6 +400,10 @@ export interface WalletPassPayment {
|
|
|
384
400
|
clearWalletRecommendList: () => void;
|
|
385
401
|
/** 清除用户识别码列表 */
|
|
386
402
|
clearUserIdentificationCodes: () => void;
|
|
403
|
+
/** 获取缓存的钱包初始化数据 */
|
|
404
|
+
getStoredWalletInitData: () => WalletStoredInitData | null;
|
|
405
|
+
/** 清除缓存的钱包初始化数据 */
|
|
406
|
+
clearStoredWalletInitData: () => void;
|
|
387
407
|
/** 清除搜索结果缓存 */
|
|
388
408
|
clearSearchResults: () => void;
|
|
389
409
|
/** 清除所有缓存数据 */
|
|
@@ -5,20 +5,22 @@ export * from './types';
|
|
|
5
5
|
export declare class SalesSummaryModule extends BaseModule implements Module, SalesSummaryModuleAPI {
|
|
6
6
|
protected defaultName: string;
|
|
7
7
|
protected defaultVersion: string;
|
|
8
|
-
private
|
|
8
|
+
private appPlugin;
|
|
9
9
|
private store;
|
|
10
10
|
private request;
|
|
11
11
|
constructor(name?: string, version?: string);
|
|
12
12
|
initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
|
|
13
13
|
getSurchargeList(): Promise<void>;
|
|
14
|
+
private getAppData;
|
|
15
|
+
private getTaxConfig;
|
|
14
16
|
getSummary(params: {
|
|
15
17
|
products: any[];
|
|
16
18
|
isPriceIncludeTax?: number;
|
|
17
19
|
taxRate?: number;
|
|
18
20
|
shopDiscount?: string | number;
|
|
19
21
|
}): Promise<{
|
|
20
|
-
tax_title:
|
|
21
|
-
tax_rate:
|
|
22
|
+
tax_title: string;
|
|
23
|
+
tax_rate: number | undefined;
|
|
22
24
|
product_quantity: number;
|
|
23
25
|
product_original_amount: string;
|
|
24
26
|
product_amount: string;
|
|
@@ -42,8 +44,8 @@ export declare class SalesSummaryModule extends BaseModule implements Module, Sa
|
|
|
42
44
|
pay_service_charge_amount: string;
|
|
43
45
|
is_price_include_tax?: number | undefined;
|
|
44
46
|
} | {
|
|
45
|
-
tax_title:
|
|
46
|
-
tax_rate:
|
|
47
|
+
tax_title: string;
|
|
48
|
+
tax_rate: number | undefined;
|
|
47
49
|
product_quantity: number;
|
|
48
50
|
product_original_amount: string;
|
|
49
51
|
product_amount: string;
|
|
@@ -27,6 +27,11 @@ var import_BaseModule = require("../BaseModule");
|
|
|
27
27
|
var import_Schedule = require("../Schedule");
|
|
28
28
|
var import_utils = require("./utils");
|
|
29
29
|
__reExport(SalesSummary_exports, require("./types"), module.exports);
|
|
30
|
+
var salesSummaryDataKeys = {
|
|
31
|
+
isPriceIncludeTax: "is_price_include_tax",
|
|
32
|
+
taxRate: "tax_rate",
|
|
33
|
+
taxTitle: "tax_title"
|
|
34
|
+
};
|
|
30
35
|
var SalesSummaryModule = class extends import_BaseModule.BaseModule {
|
|
31
36
|
constructor(name, version) {
|
|
32
37
|
super(name, version);
|
|
@@ -37,12 +42,12 @@ var SalesSummaryModule = class extends import_BaseModule.BaseModule {
|
|
|
37
42
|
var _a, _b;
|
|
38
43
|
this.core = core;
|
|
39
44
|
this.store = options.store;
|
|
40
|
-
this.
|
|
45
|
+
this.appPlugin = this.core.getPlugin("app");
|
|
41
46
|
this.request = this.core.getPlugin("request");
|
|
42
47
|
this.store.surchargeList = ((_a = options.initialState) == null ? void 0 : _a.surchargeList) || [];
|
|
43
48
|
this.store.summary = ((_b = options.initialState) == null ? void 0 : _b.summary) || (0, import_utils.createEmptySalesSummary)();
|
|
44
|
-
if (!this.
|
|
45
|
-
throw new Error("SalesSummaryModule 需要
|
|
49
|
+
if (!this.appPlugin) {
|
|
50
|
+
throw new Error("SalesSummaryModule 需要 app 插件支持");
|
|
46
51
|
}
|
|
47
52
|
if (!this.request) {
|
|
48
53
|
throw new Error("SalesSummaryModule 需要 request 插件支持");
|
|
@@ -66,10 +71,25 @@ var SalesSummaryModule = class extends import_BaseModule.BaseModule {
|
|
|
66
71
|
this.store.surchargeList = [];
|
|
67
72
|
}
|
|
68
73
|
}
|
|
74
|
+
getAppData(key) {
|
|
75
|
+
var _a, _b, _c, _d, _e, _f;
|
|
76
|
+
const getData = (_b = (_a = this.appPlugin).getData) == null ? void 0 : _b.call(_a);
|
|
77
|
+
if (typeof getData === "function")
|
|
78
|
+
return getData(key);
|
|
79
|
+
const app = this.appPlugin.getApp();
|
|
80
|
+
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");
|
|
81
|
+
return coreData == null ? void 0 : coreData[key];
|
|
82
|
+
}
|
|
83
|
+
getTaxConfig() {
|
|
84
|
+
return {
|
|
85
|
+
isPriceIncludeTax: this.getAppData(salesSummaryDataKeys.isPriceIncludeTax),
|
|
86
|
+
taxRate: this.getAppData(salesSummaryDataKeys.taxRate),
|
|
87
|
+
taxTitle: this.getAppData(salesSummaryDataKeys.taxTitle)
|
|
88
|
+
};
|
|
89
|
+
}
|
|
69
90
|
async getSummary(params) {
|
|
70
|
-
var _a, _b;
|
|
71
91
|
const { products = [], isPriceIncludeTax, taxRate, shopDiscount } = params;
|
|
72
|
-
const
|
|
92
|
+
const taxConfig = this.getTaxConfig();
|
|
73
93
|
const summarySchedule = this.core.getModule(
|
|
74
94
|
`${this.name.split("_")[0]}_schedule`
|
|
75
95
|
);
|
|
@@ -83,8 +103,8 @@ var SalesSummaryModule = class extends import_BaseModule.BaseModule {
|
|
|
83
103
|
}
|
|
84
104
|
const summary = (0, import_utils.calculateSalesSummary)({
|
|
85
105
|
products,
|
|
86
|
-
isPriceIncludeTax: isPriceIncludeTax ??
|
|
87
|
-
taxRate: taxRate ??
|
|
106
|
+
isPriceIncludeTax: isPriceIncludeTax ?? taxConfig.isPriceIncludeTax ?? 1,
|
|
107
|
+
taxRate: taxRate ?? taxConfig.taxRate,
|
|
88
108
|
surchargeList: this.store.surchargeList,
|
|
89
109
|
scheduleById,
|
|
90
110
|
isInScheduleByDate: import_Schedule.ScheduleModule.isInScheduleByDate,
|
|
@@ -92,8 +112,8 @@ var SalesSummaryModule = class extends import_BaseModule.BaseModule {
|
|
|
92
112
|
});
|
|
93
113
|
const summaryWithTaxMeta = {
|
|
94
114
|
...summary,
|
|
95
|
-
tax_title:
|
|
96
|
-
tax_rate: taxRate ??
|
|
115
|
+
tax_title: taxConfig.taxTitle || "",
|
|
116
|
+
tax_rate: taxRate ?? taxConfig.taxRate
|
|
97
117
|
};
|
|
98
118
|
this.store.summary = summaryWithTaxMeta;
|
|
99
119
|
return summaryWithTaxMeta;
|
package/lib/plugins/app.d.ts
CHANGED
package/lib/server/index.d.ts
CHANGED
|
@@ -372,13 +372,10 @@ declare class Server {
|
|
|
372
372
|
*/
|
|
373
373
|
private recomputeAndNotifyBookingQuery;
|
|
374
374
|
/**
|
|
375
|
-
*
|
|
376
|
-
* @param products 所有商品列表
|
|
377
|
-
* @param activeMenuList 生效的餐牌列表
|
|
378
|
-
* @returns 过滤后的商品列表
|
|
375
|
+
* 根据餐牌配置提取轻量商品范围。
|
|
379
376
|
* @private
|
|
380
377
|
*/
|
|
381
|
-
private
|
|
378
|
+
private getProductScopeByMenuConfig;
|
|
382
379
|
/**
|
|
383
380
|
* 记录信息日志
|
|
384
381
|
* @param title 日志标题
|
package/lib/server/index.js
CHANGED
|
@@ -2060,16 +2060,16 @@ var Server = class {
|
|
|
2060
2060
|
if (product_id != null && Number.isFinite(Number(product_id))) {
|
|
2061
2061
|
const pid = Number(product_id);
|
|
2062
2062
|
const tPrice2 = performance.now();
|
|
2063
|
-
const
|
|
2063
|
+
const allProductsWithPrice = await this.products.getProductsWithPrice(schedule_date, {
|
|
2064
2064
|
scheduleModule: this.getSchedule()
|
|
2065
2065
|
}, {
|
|
2066
2066
|
changedIds: options == null ? void 0 : options.changedIds
|
|
2067
2067
|
});
|
|
2068
2068
|
(0, import_product.perfMark)("computeQuery.getProductsWithPrice(single)", performance.now() - tPrice2, {
|
|
2069
|
-
count:
|
|
2069
|
+
count: allProductsWithPrice.length,
|
|
2070
2070
|
productId: pid
|
|
2071
2071
|
});
|
|
2072
|
-
const published =
|
|
2072
|
+
const published = allProductsWithPrice.filter((p) => ((p == null ? void 0 : p.status) || "published") === "published");
|
|
2073
2073
|
const item = published.find((p) => Number(p.id) === pid) ?? null;
|
|
2074
2074
|
(0, import_product.perfMark)("computeProductQueryResult", performance.now() - tTotal, {
|
|
2075
2075
|
mode: "single",
|
|
@@ -2108,22 +2108,26 @@ var Server = class {
|
|
|
2108
2108
|
activeMenu: activeMenuList.length
|
|
2109
2109
|
});
|
|
2110
2110
|
}
|
|
2111
|
+
const tFilter = performance.now();
|
|
2112
|
+
const productScope = this.getProductScopeByMenuConfig(activeMenuList);
|
|
2113
|
+
const scopedProductIds = this.products.getProductIdsByScope(productScope);
|
|
2114
|
+
(0, import_product.perfMark)("computeQuery.filterByMenu", performance.now() - tFilter, {
|
|
2115
|
+
scopedProductCount: scopedProductIds.length,
|
|
2116
|
+
activeMenuCount: activeMenuList.length,
|
|
2117
|
+
isAllProducts: !!productScope.isAllProducts
|
|
2118
|
+
});
|
|
2111
2119
|
const tPrice = performance.now();
|
|
2112
|
-
|
|
2120
|
+
let filteredProducts = scopedProductIds.length > 0 ? await this.products.getProductsWithPrice(schedule_date, {
|
|
2113
2121
|
scheduleModule: this.getSchedule(),
|
|
2114
2122
|
schedule_datetime,
|
|
2115
2123
|
customer_id
|
|
2116
2124
|
}, {
|
|
2117
|
-
changedIds: options == null ? void 0 : options.changedIds
|
|
2118
|
-
|
|
2125
|
+
changedIds: options == null ? void 0 : options.changedIds,
|
|
2126
|
+
productIds: productScope.isAllProducts ? void 0 : scopedProductIds
|
|
2127
|
+
}) : [];
|
|
2119
2128
|
(0, import_product.perfMark)("computeQuery.getProductsWithPrice", performance.now() - tPrice, {
|
|
2120
|
-
count:
|
|
2121
|
-
|
|
2122
|
-
const tFilter = performance.now();
|
|
2123
|
-
let filteredProducts = this.filterProductsByMenuConfig(allProductsWithPrice, activeMenuList);
|
|
2124
|
-
(0, import_product.perfMark)("computeQuery.filterByMenu", performance.now() - tFilter, {
|
|
2125
|
-
before: allProductsWithPrice.length,
|
|
2126
|
-
after: filteredProducts.length
|
|
2129
|
+
count: filteredProducts.length,
|
|
2130
|
+
scopedProductCount: scopedProductIds.length
|
|
2127
2131
|
});
|
|
2128
2132
|
const tStatus = performance.now();
|
|
2129
2133
|
const beforeStatusCount = filteredProducts.length;
|
|
@@ -2141,12 +2145,12 @@ var Server = class {
|
|
|
2141
2145
|
});
|
|
2142
2146
|
(0, import_product.perfMark)("computeQuery.sort", performance.now() - tSort, { count: filteredProducts.length });
|
|
2143
2147
|
(0, import_product.perfMark)("computeProductQueryResult", performance.now() - tTotal, {
|
|
2144
|
-
|
|
2148
|
+
scopedProductCount: scopedProductIds.length,
|
|
2145
2149
|
filteredCount: filteredProducts.length,
|
|
2146
2150
|
activeMenuCount: activeMenuList.length
|
|
2147
2151
|
});
|
|
2148
2152
|
this.logInfo("computeProductQueryResult 完成", {
|
|
2149
|
-
|
|
2153
|
+
scopedProductCount: scopedProductIds.length,
|
|
2150
2154
|
filteredCount: filteredProducts.length,
|
|
2151
2155
|
activeMenuCount: activeMenuList.length
|
|
2152
2156
|
});
|
|
@@ -2249,29 +2253,25 @@ var Server = class {
|
|
|
2249
2253
|
}
|
|
2250
2254
|
}
|
|
2251
2255
|
/**
|
|
2252
|
-
*
|
|
2253
|
-
* @param products 所有商品列表
|
|
2254
|
-
* @param activeMenuList 生效的餐牌列表
|
|
2255
|
-
* @returns 过滤后的商品列表
|
|
2256
|
+
* 根据餐牌配置提取轻量商品范围。
|
|
2256
2257
|
* @private
|
|
2257
2258
|
*/
|
|
2258
|
-
|
|
2259
|
+
getProductScopeByMenuConfig(activeMenuList) {
|
|
2259
2260
|
if (!activeMenuList || activeMenuList.length === 0) {
|
|
2260
2261
|
console.log("[Server] 没有生效的餐牌,返回空数组");
|
|
2261
|
-
this.logInfo("
|
|
2262
|
-
productCount: products.length,
|
|
2262
|
+
this.logInfo("getProductScopeByMenuConfig: 没有生效的餐牌,返回空数组", {
|
|
2263
2263
|
activeMenuCount: 0
|
|
2264
2264
|
});
|
|
2265
|
-
return [];
|
|
2265
|
+
return { productIds: [], collectionIds: [] };
|
|
2266
2266
|
}
|
|
2267
|
-
|
|
2268
|
-
|
|
2267
|
+
const allowedProductIds = /* @__PURE__ */ new Set();
|
|
2268
|
+
const allowedCollectionIds = /* @__PURE__ */ new Set();
|
|
2269
2269
|
let hasProductAll = false;
|
|
2270
2270
|
for (const menu of activeMenuList) {
|
|
2271
2271
|
const config = menu.partyroom_package;
|
|
2272
2272
|
if (!config) {
|
|
2273
2273
|
console.warn("[Server] 餐牌缺少 partyroom_package 配置:", menu);
|
|
2274
|
-
this.logWarning("
|
|
2274
|
+
this.logWarning("getProductScopeByMenuConfig: 餐牌缺少 partyroom_package 配置", {
|
|
2275
2275
|
menuId: menu.form_record_id,
|
|
2276
2276
|
menuName: menu.name
|
|
2277
2277
|
});
|
|
@@ -2279,7 +2279,7 @@ var Server = class {
|
|
|
2279
2279
|
}
|
|
2280
2280
|
if (config.type === "product_all") {
|
|
2281
2281
|
console.log("[Server] 餐牌允许所有商品:", menu.name);
|
|
2282
|
-
this.logInfo("
|
|
2282
|
+
this.logInfo("getProductScopeByMenuConfig: 餐牌允许所有商品", {
|
|
2283
2283
|
menuId: menu.form_record_id,
|
|
2284
2284
|
menuName: menu.name,
|
|
2285
2285
|
configType: config.type
|
|
@@ -2291,7 +2291,7 @@ var Server = class {
|
|
|
2291
2291
|
const productIds = config.products.map((item) => item.product_id);
|
|
2292
2292
|
productIds.forEach((id) => id && allowedProductIds.add(id));
|
|
2293
2293
|
console.log("[Server] 餐牌允许指定商品 (product_ids):", menu.name, productIds);
|
|
2294
|
-
this.logInfo("
|
|
2294
|
+
this.logInfo("getProductScopeByMenuConfig: 餐牌允许指定商品", {
|
|
2295
2295
|
menuId: menu.form_record_id,
|
|
2296
2296
|
menuName: menu.name,
|
|
2297
2297
|
configType: config.type,
|
|
@@ -2302,7 +2302,7 @@ var Server = class {
|
|
|
2302
2302
|
const collectionIds = config.products.map((item) => item.product_collection_id);
|
|
2303
2303
|
collectionIds.forEach((id) => id && allowedCollectionIds.add(id));
|
|
2304
2304
|
console.log("[Server] 餐牌允许商品集合 (product_collection):", menu.name, collectionIds);
|
|
2305
|
-
this.logInfo("
|
|
2305
|
+
this.logInfo("getProductScopeByMenuConfig: 餐牌允许商品集合", {
|
|
2306
2306
|
menuId: menu.form_record_id,
|
|
2307
2307
|
menuName: menu.name,
|
|
2308
2308
|
configType: config.type,
|
|
@@ -2311,48 +2311,28 @@ var Server = class {
|
|
|
2311
2311
|
}
|
|
2312
2312
|
}
|
|
2313
2313
|
if (hasProductAll) {
|
|
2314
|
-
this.logInfo("
|
|
2315
|
-
|
|
2316
|
-
});
|
|
2317
|
-
return products;
|
|
2314
|
+
this.logInfo("getProductScopeByMenuConfig: 返回所有商品 scope(product_all)");
|
|
2315
|
+
return { isAllProducts: true };
|
|
2318
2316
|
}
|
|
2319
2317
|
if (allowedProductIds.size === 0 && allowedCollectionIds.size === 0) {
|
|
2320
2318
|
console.log("[Server] 没有允许的商品和集合");
|
|
2321
|
-
this.logWarning("
|
|
2322
|
-
productCount: products.length,
|
|
2319
|
+
this.logWarning("getProductScopeByMenuConfig: 没有允许的商品和集合", {
|
|
2323
2320
|
activeMenuCount: activeMenuList.length
|
|
2324
2321
|
});
|
|
2325
|
-
return [];
|
|
2322
|
+
return { productIds: [], collectionIds: [] };
|
|
2326
2323
|
}
|
|
2327
2324
|
const allowedProductIdsArray = Array.from(allowedProductIds);
|
|
2328
2325
|
const allowedCollectionIdsArray = Array.from(allowedCollectionIds);
|
|
2329
2326
|
console.log("[Server] 允许的商品 IDs:", allowedProductIdsArray);
|
|
2330
2327
|
console.log("[Server] 允许的集合 IDs:", allowedCollectionIdsArray);
|
|
2331
|
-
this.logInfo("
|
|
2328
|
+
this.logInfo("getProductScopeByMenuConfig: 收集到的允许规则", {
|
|
2332
2329
|
allowedProductCount: allowedProductIds.size,
|
|
2333
2330
|
allowedCollectionCount: allowedCollectionIds.size
|
|
2334
2331
|
});
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
if (allowedCollectionIds.size > 0 && Array.isArray(product.collection)) {
|
|
2340
|
-
const hasMatchingCollection = product.collection.some(
|
|
2341
|
-
(col) => allowedCollectionIds.has(col.id)
|
|
2342
|
-
);
|
|
2343
|
-
if (hasMatchingCollection) {
|
|
2344
|
-
return true;
|
|
2345
|
-
}
|
|
2346
|
-
}
|
|
2347
|
-
return false;
|
|
2348
|
-
});
|
|
2349
|
-
console.log("[Server] 过滤结果: 原始 %d 个,过滤后 %d 个", products.length, filteredProducts.length);
|
|
2350
|
-
this.logInfo("filterProductsByMenuConfig: 过滤完成", {
|
|
2351
|
-
originalCount: products.length,
|
|
2352
|
-
filteredCount: filteredProducts.length,
|
|
2353
|
-
removedCount: products.length - filteredProducts.length
|
|
2354
|
-
});
|
|
2355
|
-
return filteredProducts;
|
|
2332
|
+
return {
|
|
2333
|
+
productIds: allowedProductIdsArray,
|
|
2334
|
+
collectionIds: allowedCollectionIdsArray
|
|
2335
|
+
};
|
|
2356
2336
|
}
|
|
2357
2337
|
/**
|
|
2358
2338
|
* 记录信息日志
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* 包含新增的 Products、Menu、Quotation 和扩展的 Schedule 模块
|
|
4
4
|
*/
|
|
5
5
|
export { ProductsModule } from './products';
|
|
6
|
-
export type { ProductsState } from './products/types';
|
|
6
|
+
export type { ProductIdScope, ProductsState } from './products/types';
|
|
7
7
|
export { ProductsHooks } from './products/types';
|
|
8
8
|
export { MenuModule } from './menu';
|
|
9
9
|
export type { MenuState, MenuData } from './menu/types';
|