@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.
Files changed (92) hide show
  1. package/dist/core/index.js +1 -0
  2. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  3. package/dist/modules/Cart/utils/cartProduct.js +1 -1
  4. package/dist/modules/Discount/index.d.ts +6 -2
  5. package/dist/modules/Discount/index.js +14 -8
  6. package/dist/modules/Order/index.d.ts +2 -0
  7. package/dist/modules/Order/index.js +234 -161
  8. package/dist/modules/Order/types.d.ts +19 -0
  9. package/dist/modules/Order/utils.js +7 -6
  10. package/dist/modules/Payment/index.d.ts +4 -0
  11. package/dist/modules/Payment/index.js +567 -505
  12. package/dist/modules/Payment/types.d.ts +29 -9
  13. package/dist/modules/SalesSummary/index.d.ts +7 -5
  14. package/dist/modules/SalesSummary/index.js +35 -11
  15. package/dist/plugins/app.d.ts +2 -0
  16. package/dist/server/index.d.ts +2 -5
  17. package/dist/server/index.js +58 -66
  18. package/dist/server/modules/index.d.ts +1 -1
  19. package/dist/server/modules/products/index.d.ts +12 -1
  20. package/dist/server/modules/products/index.js +169 -78
  21. package/dist/server/modules/products/types.d.ts +11 -0
  22. package/dist/server/modules/products/types.js +4 -0
  23. package/dist/server/utils/product.js +2 -2
  24. package/dist/solution/BaseSales/index.d.ts +26 -2
  25. package/dist/solution/BaseSales/index.js +342 -112
  26. package/dist/solution/BaseSales/types.d.ts +4 -4
  27. package/dist/solution/BaseSales/types.js +4 -4
  28. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +62 -0
  29. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +116 -0
  30. package/dist/solution/BaseSales/utils.js +3 -3
  31. package/dist/solution/BookingByStep/index.d.ts +1 -1
  32. package/dist/solution/BookingTicket/index.d.ts +11 -13
  33. package/dist/solution/BookingTicket/index.js +23 -37
  34. package/dist/solution/BookingTicket/types.d.ts +9 -6
  35. package/dist/solution/BookingTicket/types.js +6 -3
  36. package/dist/solution/BookingTicket/utils/cartView.d.ts +7 -12
  37. package/dist/solution/BookingTicket/utils/cartView.js +52 -14
  38. package/dist/solution/BookingTicket/utils/orderCustomer.d.ts +4 -0
  39. package/dist/solution/BookingTicket/utils/orderCustomer.js +31 -0
  40. package/dist/solution/Sales/index.d.ts +3 -0
  41. package/dist/solution/Sales/index.js +85 -43
  42. package/dist/solution/Sales/types.d.ts +3 -0
  43. package/dist/solution/ScanOrder/types.d.ts +4 -4
  44. package/dist/solution/ScanOrder/types.js +4 -4
  45. package/dist/solution/ScanOrder/utils.js +3 -3
  46. package/dist/solution/ShopDiscount/index.d.ts +2 -1
  47. package/dist/solution/ShopDiscount/index.js +32 -20
  48. package/dist/solution/ShopDiscount/types.d.ts +1 -0
  49. package/lib/core/index.js +1 -0
  50. package/lib/modules/Cart/utils/cartProduct.js +1 -1
  51. package/lib/modules/Discount/index.d.ts +6 -2
  52. package/lib/modules/Discount/index.js +3 -1
  53. package/lib/modules/Order/index.d.ts +2 -0
  54. package/lib/modules/Order/index.js +40 -8
  55. package/lib/modules/Order/types.d.ts +19 -0
  56. package/lib/modules/Order/utils.js +4 -2
  57. package/lib/modules/Payment/index.d.ts +4 -0
  58. package/lib/modules/Payment/index.js +26 -2
  59. package/lib/modules/Payment/types.d.ts +29 -9
  60. package/lib/modules/SalesSummary/index.d.ts +7 -5
  61. package/lib/modules/SalesSummary/index.js +29 -9
  62. package/lib/plugins/app.d.ts +2 -0
  63. package/lib/server/index.d.ts +2 -5
  64. package/lib/server/index.js +38 -58
  65. package/lib/server/modules/index.d.ts +1 -1
  66. package/lib/server/modules/products/index.d.ts +12 -1
  67. package/lib/server/modules/products/index.js +69 -9
  68. package/lib/server/modules/products/types.d.ts +11 -0
  69. package/lib/server/utils/product.js +2 -2
  70. package/lib/solution/BaseSales/index.d.ts +26 -2
  71. package/lib/solution/BaseSales/index.js +169 -3
  72. package/lib/solution/BaseSales/types.d.ts +4 -4
  73. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +62 -0
  74. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +155 -0
  75. package/lib/solution/BaseSales/utils.js +3 -3
  76. package/lib/solution/BookingByStep/index.d.ts +1 -1
  77. package/lib/solution/BookingTicket/index.d.ts +11 -13
  78. package/lib/solution/BookingTicket/index.js +17 -27
  79. package/lib/solution/BookingTicket/types.d.ts +9 -6
  80. package/lib/solution/BookingTicket/utils/cartView.d.ts +7 -12
  81. package/lib/solution/BookingTicket/utils/cartView.js +44 -18
  82. package/lib/solution/BookingTicket/utils/orderCustomer.d.ts +4 -0
  83. package/lib/solution/BookingTicket/utils/orderCustomer.js +58 -0
  84. package/lib/solution/Sales/index.d.ts +3 -0
  85. package/lib/solution/Sales/index.js +50 -15
  86. package/lib/solution/Sales/types.d.ts +3 -0
  87. package/lib/solution/ScanOrder/types.d.ts +4 -4
  88. package/lib/solution/ScanOrder/utils.js +3 -3
  89. package/lib/solution/ShopDiscount/index.d.ts +2 -1
  90. package/lib/solution/ShopDiscount/index.js +10 -4
  91. package/lib/solution/ShopDiscount/types.d.ts +1 -0
  92. 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 existedFingerprint = (0, import_utils3.buildProductLineFingerprint)(
1038
+ const existedFingerprint2 = (0, import_utils3.buildProductLineFingerprint)(
1022
1039
  item.product_option_item,
1023
1040
  item.product_bundle
1024
1041
  );
1025
- return existedFingerprint === incomingFingerprint;
1042
+ return existedFingerprint2 === incomingFingerprint;
1026
1043
  });
1027
- if (matchedIndex === -1) {
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 = tempOrder.products[matchedIndex];
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", "scheduleEvents", "payments", "customer", "summary", "contacts_info"]
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", "scheduleEvents"]
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: (d == null ? void 0 : d.option_group_item_id) ?? (d == null ? void 0 : d.product_option_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 || []).map((booking) => normalizeSubmitBooking(booking)),
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) => Promise<SearchIdentificationCodeResult>;
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 shopStore;
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: any;
21
- tax_rate: any;
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: any;
46
- tax_rate: any;
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.shopStore = this.core.getPlugin("shopStore");
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.shopStore) {
45
- throw new Error("SalesSummaryModule 需要 shopStore 插件支持");
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 shopInfo = ((_b = (_a = this.shopStore.get("core")) == null ? void 0 : _a.core) == null ? void 0 : _b.shop) || {};
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 ?? (shopInfo == null ? void 0 : shopInfo.is_price_include_tax) ?? 1,
87
- taxRate: taxRate ?? (shopInfo == null ? void 0 : shopInfo.tax_rate),
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: (shopInfo == null ? void 0 : shopInfo.tax_title) || "",
96
- tax_rate: taxRate ?? (shopInfo == null ? void 0 : shopInfo.tax_rate)
115
+ tax_title: taxConfig.taxTitle || "",
116
+ tax_rate: taxRate ?? taxConfig.taxRate
97
117
  };
98
118
  this.store.summary = summaryWithTaxMeta;
99
119
  return summaryWithTaxMeta;
@@ -1,8 +1,10 @@
1
1
  import { Plugin } from '../types';
2
2
  import App from './app-types/app';
3
+ export type AppDataGetter = (key: string) => any;
3
4
  /**
4
5
  * AppPlugin 接口定义
5
6
  */
6
7
  export interface AppPlugin extends Plugin {
7
8
  getApp: () => App;
9
+ getData?: () => AppDataGetter;
8
10
  }
@@ -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 filterProductsByMenuConfig;
378
+ private getProductScopeByMenuConfig;
382
379
  /**
383
380
  * 记录信息日志
384
381
  * @param title 日志标题
@@ -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 allProductsWithPrice2 = await this.products.getProductsWithPrice(schedule_date, {
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: allProductsWithPrice2.length,
2069
+ count: allProductsWithPrice.length,
2070
2070
  productId: pid
2071
2071
  });
2072
- const published = allProductsWithPrice2.filter((p) => ((p == null ? void 0 : p.status) || "published") === "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
- const allProductsWithPrice = await this.products.getProductsWithPrice(schedule_date, {
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: allProductsWithPrice.length
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
- originalCount: allProductsWithPrice.length,
2148
+ scopedProductCount: scopedProductIds.length,
2145
2149
  filteredCount: filteredProducts.length,
2146
2150
  activeMenuCount: activeMenuList.length
2147
2151
  });
2148
2152
  this.logInfo("computeProductQueryResult 完成", {
2149
- originalCount: allProductsWithPrice.length,
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
- filterProductsByMenuConfig(products, activeMenuList) {
2259
+ getProductScopeByMenuConfig(activeMenuList) {
2259
2260
  if (!activeMenuList || activeMenuList.length === 0) {
2260
2261
  console.log("[Server] 没有生效的餐牌,返回空数组");
2261
- this.logInfo("filterProductsByMenuConfig: 没有生效的餐牌,返回空数组", {
2262
- productCount: products.length,
2262
+ this.logInfo("getProductScopeByMenuConfig: 没有生效的餐牌,返回空数组", {
2263
2263
  activeMenuCount: 0
2264
2264
  });
2265
- return [];
2265
+ return { productIds: [], collectionIds: [] };
2266
2266
  }
2267
- let allowedProductIds = /* @__PURE__ */ new Set();
2268
- let allowedCollectionIds = /* @__PURE__ */ new Set();
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("filterProductsByMenuConfig: 餐牌缺少 partyroom_package 配置", {
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("filterProductsByMenuConfig: 餐牌允许所有商品", {
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("filterProductsByMenuConfig: 餐牌允许指定商品", {
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("filterProductsByMenuConfig: 餐牌允许商品集合", {
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("filterProductsByMenuConfig: 返回所有商品(product_all)", {
2315
- productCount: products.length
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("filterProductsByMenuConfig: 没有允许的商品和集合", {
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("filterProductsByMenuConfig: 收集到的允许规则", {
2328
+ this.logInfo("getProductScopeByMenuConfig: 收集到的允许规则", {
2332
2329
  allowedProductCount: allowedProductIds.size,
2333
2330
  allowedCollectionCount: allowedCollectionIds.size
2334
2331
  });
2335
- const filteredProducts = products.filter((product) => {
2336
- if (allowedProductIds.has(product.id)) {
2337
- return true;
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';