@pisell/pisellos 2.3.42 → 2.3.44

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 (157) hide show
  1. package/dist/modules/Discount/index.d.ts +1 -0
  2. package/dist/modules/Discount/index.js +40 -11
  3. package/dist/modules/Discount/types.d.ts +1 -0
  4. package/dist/modules/Holder/index.d.ts +48 -0
  5. package/dist/modules/Holder/index.js +640 -0
  6. package/dist/modules/Holder/types.d.ts +123 -0
  7. package/dist/modules/Holder/types.js +1 -0
  8. package/dist/modules/Holder/utils.d.ts +13 -0
  9. package/dist/modules/Holder/utils.js +34 -0
  10. package/dist/modules/OpenData/index.js +2 -2
  11. package/dist/modules/Order/index.d.ts +5 -2
  12. package/dist/modules/Order/index.js +127 -53
  13. package/dist/modules/Order/types.d.ts +11 -0
  14. package/dist/modules/Order/utils.d.ts +10 -0
  15. package/dist/modules/Order/utils.js +35 -3
  16. package/dist/modules/Payment/walletpass.d.ts +10 -3
  17. package/dist/modules/Payment/walletpass.js +425 -282
  18. package/dist/modules/Product/types.d.ts +1 -0
  19. package/dist/modules/ProductList/index.js +33 -14
  20. package/dist/modules/Quotation/index.d.ts +1 -1
  21. package/dist/modules/Quotation/index.js +2 -2
  22. package/dist/modules/ResourcePlanner/index.d.ts +24 -0
  23. package/dist/modules/ResourcePlanner/index.js +181 -0
  24. package/dist/modules/ResourcePlanner/planner.d.ts +14 -0
  25. package/dist/modules/ResourcePlanner/planner.js +1069 -0
  26. package/dist/modules/ResourcePlanner/types.d.ts +227 -0
  27. package/dist/modules/ResourcePlanner/types.js +1 -0
  28. package/dist/modules/Rules/index.d.ts +2 -0
  29. package/dist/modules/Rules/index.js +106 -68
  30. package/dist/modules/SalesSummary/index.js +12 -13
  31. package/dist/modules/ScanOrderLogger/index.d.ts +2 -0
  32. package/dist/modules/ScanOrderLogger/index.js +15 -2
  33. package/dist/modules/ScanOrderLogger/providers/feishu.js +45 -27
  34. package/dist/modules/ScanOrderLogger/types.d.ts +1 -0
  35. package/dist/modules/Schedule/index.d.ts +3 -1
  36. package/dist/modules/Schedule/index.js +21 -16
  37. package/dist/modules/Summary/utils.js +38 -13
  38. package/dist/modules/index.d.ts +2 -0
  39. package/dist/modules/index.js +3 -1
  40. package/dist/plugins/window.d.ts +1 -0
  41. package/dist/server/index.d.ts +14 -0
  42. package/dist/server/index.js +772 -657
  43. package/dist/solution/BaseSales/index.d.ts +7 -0
  44. package/dist/solution/BaseSales/index.js +70 -45
  45. package/dist/solution/BaseSales/types.d.ts +3 -1
  46. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +6 -3
  47. package/dist/solution/BookingByStep/index.d.ts +17 -2
  48. package/dist/solution/BookingByStep/index.js +294 -215
  49. package/dist/solution/BookingByStep/types.d.ts +2 -1
  50. package/dist/solution/BookingByStep/types.js +3 -1
  51. package/dist/solution/BookingByStep/utils/capacity.js +17 -1
  52. package/dist/solution/BookingByStep/utils/timeslots.d.ts +3 -1
  53. package/dist/solution/BookingByStep/utils/timeslots.js +19 -12
  54. package/dist/solution/BookingTicket/index.js +8 -5
  55. package/dist/solution/BookingTicket/types.d.ts +1 -0
  56. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +3 -3
  57. package/dist/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
  58. package/dist/solution/BookingTicket/utils/scan/handleScan.js +10 -2
  59. package/dist/solution/ScanOrder/index.d.ts +26 -14
  60. package/dist/solution/ScanOrder/index.js +1142 -739
  61. package/dist/solution/ScanOrder/types.d.ts +21 -1
  62. package/dist/solution/ScanOrder/utils.d.ts +8 -0
  63. package/dist/solution/ScanOrder/utils.js +66 -25
  64. package/dist/solution/ShopDiscount/index.d.ts +1 -0
  65. package/dist/solution/ShopDiscount/index.js +125 -87
  66. package/dist/solution/UnifiedBookingSales/index.d.ts +183 -0
  67. package/dist/solution/UnifiedBookingSales/index.js +1891 -0
  68. package/dist/solution/UnifiedBookingSales/types.d.ts +143 -0
  69. package/dist/solution/UnifiedBookingSales/types.js +11 -0
  70. package/dist/solution/VenueBooking/index.d.ts +40 -11
  71. package/dist/solution/VenueBooking/index.js +1167 -841
  72. package/dist/solution/VenueBooking/types.d.ts +3 -0
  73. package/dist/solution/VenueBooking/utils/resource.js +1 -0
  74. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +4 -4
  75. package/dist/solution/VenueBooking/utils/slotMerge.js +10 -5
  76. package/dist/solution/index.d.ts +1 -0
  77. package/dist/solution/index.js +2 -1
  78. package/dist/types/index.d.ts +1 -0
  79. package/lib/modules/Discount/index.d.ts +1 -0
  80. package/lib/modules/Discount/index.js +9 -0
  81. package/lib/modules/Discount/types.d.ts +1 -0
  82. package/lib/modules/Holder/index.d.ts +48 -0
  83. package/lib/modules/Holder/index.js +402 -0
  84. package/lib/modules/Holder/types.d.ts +123 -0
  85. package/lib/modules/Holder/types.js +17 -0
  86. package/lib/modules/Holder/utils.d.ts +13 -0
  87. package/lib/modules/Holder/utils.js +71 -0
  88. package/lib/modules/OpenData/index.js +1 -1
  89. package/lib/modules/Order/index.d.ts +5 -2
  90. package/lib/modules/Order/index.js +72 -17
  91. package/lib/modules/Order/types.d.ts +11 -0
  92. package/lib/modules/Order/utils.d.ts +10 -0
  93. package/lib/modules/Order/utils.js +36 -5
  94. package/lib/modules/Payment/walletpass.d.ts +10 -3
  95. package/lib/modules/Payment/walletpass.js +218 -56
  96. package/lib/modules/Product/types.d.ts +1 -0
  97. package/lib/modules/ProductList/index.js +40 -31
  98. package/lib/modules/Quotation/index.d.ts +1 -1
  99. package/lib/modules/Quotation/index.js +2 -2
  100. package/lib/modules/ResourcePlanner/index.d.ts +24 -0
  101. package/lib/modules/ResourcePlanner/index.js +148 -0
  102. package/lib/modules/ResourcePlanner/planner.d.ts +14 -0
  103. package/lib/modules/ResourcePlanner/planner.js +933 -0
  104. package/lib/modules/ResourcePlanner/types.d.ts +227 -0
  105. package/lib/modules/ResourcePlanner/types.js +17 -0
  106. package/lib/modules/Rules/index.d.ts +2 -0
  107. package/lib/modules/Rules/index.js +41 -19
  108. package/lib/modules/SalesSummary/index.js +6 -7
  109. package/lib/modules/ScanOrderLogger/index.d.ts +2 -0
  110. package/lib/modules/ScanOrderLogger/index.js +13 -1
  111. package/lib/modules/ScanOrderLogger/providers/feishu.js +15 -6
  112. package/lib/modules/ScanOrderLogger/types.d.ts +1 -0
  113. package/lib/modules/Schedule/index.d.ts +3 -1
  114. package/lib/modules/Schedule/index.js +10 -8
  115. package/lib/modules/Summary/utils.js +21 -1
  116. package/lib/modules/index.d.ts +2 -0
  117. package/lib/modules/index.js +5 -1
  118. package/lib/plugins/window.d.ts +1 -0
  119. package/lib/server/index.d.ts +14 -0
  120. package/lib/server/index.js +65 -5
  121. package/lib/solution/BaseSales/index.d.ts +7 -0
  122. package/lib/solution/BaseSales/index.js +25 -8
  123. package/lib/solution/BaseSales/types.d.ts +3 -1
  124. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +3 -2
  125. package/lib/solution/BookingByStep/index.d.ts +17 -2
  126. package/lib/solution/BookingByStep/index.js +60 -18
  127. package/lib/solution/BookingByStep/types.d.ts +2 -1
  128. package/lib/solution/BookingByStep/types.js +5 -0
  129. package/lib/solution/BookingByStep/utils/capacity.js +20 -1
  130. package/lib/solution/BookingByStep/utils/timeslots.d.ts +3 -1
  131. package/lib/solution/BookingByStep/utils/timeslots.js +19 -11
  132. package/lib/solution/BookingTicket/index.js +11 -2
  133. package/lib/solution/BookingTicket/types.d.ts +1 -0
  134. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +2 -2
  135. package/lib/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
  136. package/lib/solution/BookingTicket/utils/scan/handleScan.js +2 -2
  137. package/lib/solution/ScanOrder/index.d.ts +26 -14
  138. package/lib/solution/ScanOrder/index.js +449 -182
  139. package/lib/solution/ScanOrder/types.d.ts +21 -1
  140. package/lib/solution/ScanOrder/utils.d.ts +8 -0
  141. package/lib/solution/ScanOrder/utils.js +31 -0
  142. package/lib/solution/ShopDiscount/index.d.ts +1 -0
  143. package/lib/solution/ShopDiscount/index.js +14 -0
  144. package/lib/solution/UnifiedBookingSales/index.d.ts +183 -0
  145. package/lib/solution/UnifiedBookingSales/index.js +1084 -0
  146. package/lib/solution/UnifiedBookingSales/types.d.ts +143 -0
  147. package/lib/solution/UnifiedBookingSales/types.js +33 -0
  148. package/lib/solution/VenueBooking/index.d.ts +40 -11
  149. package/lib/solution/VenueBooking/index.js +322 -110
  150. package/lib/solution/VenueBooking/types.d.ts +3 -0
  151. package/lib/solution/VenueBooking/utils/resource.js +1 -0
  152. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +4 -4
  153. package/lib/solution/VenueBooking/utils/slotMerge.js +6 -4
  154. package/lib/solution/index.d.ts +1 -0
  155. package/lib/solution/index.js +3 -1
  156. package/lib/types/index.d.ts +1 -0
  157. package/package.json +1 -1
@@ -21,11 +21,13 @@ export declare class WalletPassPaymentImpl implements WalletPassPayment {
21
21
  private emitEvent;
22
22
  private publishWalletAssetsState;
23
23
  private recalculateWalletAssets;
24
+ /** 获取当前缓存中所有支付类 Wallet 资产的扫码 code。 */
25
+ private getSearchedWalletAssetCodes;
24
26
  /**
25
- * 使用最新订单参数重验扫码搜索过的支付类 Wallet 资产。
26
- * 请求失败或暂时无匹配结果时保留旧资产,避免商品变化造成列表闪空。
27
+ * 用订单重算接口返回的数据更新扫码 Wallet 缓存。
28
+ * 接口暂时缺失某个扫码 code 时继续保留旧值,避免列表闪空。
27
29
  */
28
- private revalidateSearchedWalletAssets;
30
+ private syncSearchedWalletAssets;
29
31
  /**
30
32
  * 生成钱包API默认参数
31
33
  * 根据业务数据生成标准的钱包API参数,并存储在模块中
@@ -67,6 +69,11 @@ export declare class WalletPassPaymentImpl implements WalletPassPayment {
67
69
  noApplicableVoucher: any[];
68
70
  products: any[];
69
71
  }>;
72
+ /**
73
+ * 商品或订单金额变化后,使用聚合接口一次重算已选与剩余 WalletPass。
74
+ * Walk-In 不发送 customer_id;会员才携带真实 customer_id。
75
+ */
76
+ private aggregateRecalculateWalletAssetsAsync;
70
77
  getWalletPassRecommendListAsync(params: WalletDeductionRecommendParams): Promise<WalletRecommendItem[]>;
71
78
  formatWalletPassList2PreparePayments(list: WalletRecommendItem[]): {
72
79
  voucher_id: number;
@@ -41,6 +41,11 @@ function getWalletAssetKey(assetOrId) {
41
41
  const id = assetOrId && typeof assetOrId === "object" ? getWalletAssetId(assetOrId) : assetOrId;
42
42
  return id === void 0 || id === null ? "" : String(id);
43
43
  }
44
+ function matchesWalletAssetCode(asset, normalizedCode) {
45
+ return [asset == null ? void 0 : asset.code, asset == null ? void 0 : asset.encoded].some(
46
+ (identifier) => String(identifier ?? "").trim() === normalizedCode
47
+ );
48
+ }
44
49
  function isWalletAssetAvailable(asset) {
45
50
  if (!asset)
46
51
  return false;
@@ -150,12 +155,10 @@ var WalletPassPaymentImpl = class {
150
155
  const committedKeys = new Set(
151
156
  this.walletAssetsState.committedIds.map((id) => String(id))
152
157
  );
153
- const requestedKeys = new Set(
154
- requestedIds.map((id) => String(id)).filter((id) => !committedKeys.has(id))
155
- );
156
- const requested = items.filter(
157
- (item) => requestedKeys.has(getWalletAssetKey(item)) && isWalletAssetAvailable(item)
158
+ const itemsByKey = new Map(
159
+ items.map((item) => [getWalletAssetKey(item), item])
158
160
  );
161
+ const requested = requestedIds.map((id) => String(id)).filter((id) => !committedKeys.has(id)).map((id) => itemsByKey.get(id)).filter((item) => item && isWalletAssetAvailable(item));
159
162
  let nextItems = items;
160
163
  let selectedItems = requested;
161
164
  const evaluator = (_b = (_a = this.paymentModule.window) == null ? void 0 : _a.getWalletPassEvaluator) == null ? void 0 : _b.call(_a);
@@ -201,57 +204,40 @@ var WalletPassPaymentImpl = class {
201
204
  error: null
202
205
  });
203
206
  }
207
+ /** 获取当前缓存中所有支付类 Wallet 资产的扫码 code。 */
208
+ getSearchedWalletAssetCodes() {
209
+ const cachedAssets = this.searchResults.filter(isWalletPaymentAsset);
210
+ const seenCodes = /* @__PURE__ */ new Set();
211
+ return cachedAssets.map((item) => String((item == null ? void 0 : item.code) || "").trim()).filter((code) => {
212
+ const normalizedCode = code.toUpperCase();
213
+ if (!normalizedCode || seenCodes.has(normalizedCode))
214
+ return false;
215
+ seenCodes.add(normalizedCode);
216
+ return true;
217
+ });
218
+ }
204
219
  /**
205
- * 使用最新订单参数重验扫码搜索过的支付类 Wallet 资产。
206
- * 请求失败或暂时无匹配结果时保留旧资产,避免商品变化造成列表闪空。
220
+ * 用订单重算接口返回的数据更新扫码 Wallet 缓存。
221
+ * 接口暂时缺失某个扫码 code 时继续保留旧值,避免列表闪空。
207
222
  */
208
- async revalidateSearchedWalletAssets(requestSequence) {
223
+ syncSearchedWalletAssets(refreshedCandidates) {
209
224
  const cachedAssets = this.searchResults.filter(isWalletPaymentAsset);
210
- const searchCodes = [
211
- ...new Set(
212
- cachedAssets.map((item) => String((item == null ? void 0 : item.code) || "").trim()).filter(Boolean)
213
- )
214
- ];
215
- if (searchCodes.length === 0)
216
- return cachedAssets;
217
- const preparePayments = this.formatWalletPassList2PreparePayments(
218
- this.walletAssetsState.selectedItems
219
- );
220
- const refreshedGroups = await Promise.all(
221
- searchCodes.map(async (searchCode) => {
222
- try {
223
- const result = await this.searchIdentificationCodeAsync(
224
- {
225
- ...this.walletParams || {},
226
- code: searchCode,
227
- prepare_payments: preparePayments
228
- },
229
- { noCache: true }
230
- );
231
- return {
232
- searchCode,
233
- items: result.type === "normalCode" ? result.data.filter(isWalletPaymentAsset) : []
234
- };
235
- } catch (error) {
236
- this.paymentModule.logWarning(
237
- "[WalletPass] 重验扫码 Wallet 资产失败,保留旧结果",
238
- {
239
- code: searchCode,
240
- error: error instanceof Error ? error.message : String(error)
241
- }
242
- );
243
- return { searchCode, items: [] };
244
- }
245
- })
225
+ const searchedCodeKeys = new Set(
226
+ this.getSearchedWalletAssetCodes().map((code) => code.toUpperCase())
246
227
  );
247
- if (requestSequence !== this.walletAssetsRequestSequence) {
228
+ if (searchedCodeKeys.size === 0)
248
229
  return cachedAssets;
249
- }
250
- const replacedCodes = new Set(
251
- refreshedGroups.filter((group) => group.items.length > 0).map((group) => group.searchCode.toUpperCase())
230
+ const refreshedAssets = refreshedCandidates.filter(
231
+ (item) => isWalletPaymentAsset(item) && searchedCodeKeys.has(
232
+ String((item == null ? void 0 : item.code) || "").trim().toUpperCase()
233
+ )
252
234
  );
253
- const refreshedAssets = refreshedGroups.flatMap((group) => group.items);
254
235
  if (refreshedAssets.length > 0) {
236
+ const replacedCodes = new Set(
237
+ refreshedAssets.map(
238
+ (item) => String((item == null ? void 0 : item.code) || "").trim().toUpperCase()
239
+ )
240
+ );
255
241
  this.searchResults = [
256
242
  ...this.searchResults.filter(
257
243
  (item) => !replacedCodes.has(String((item == null ? void 0 : item.code) || "").trim().toUpperCase())
@@ -259,7 +245,10 @@ var WalletPassPaymentImpl = class {
259
245
  ...refreshedAssets
260
246
  ];
261
247
  }
262
- return mergeWalletAssets(cachedAssets, refreshedAssets);
248
+ return mergeWalletAssets(
249
+ cachedAssets,
250
+ refreshedAssets
251
+ );
263
252
  }
264
253
  /**
265
254
  * 生成钱包API默认参数
@@ -468,6 +457,96 @@ var WalletPassPaymentImpl = class {
468
457
  throw error;
469
458
  }
470
459
  }
460
+ /**
461
+ * 商品或订单金额变化后,使用聚合接口一次重算已选与剩余 WalletPass。
462
+ * Walk-In 不发送 customer_id;会员才携带真实 customer_id。
463
+ */
464
+ async aggregateRecalculateWalletAssetsAsync(businessData, selectedIds) {
465
+ var _a, _b;
466
+ const walletParams = this.generateWalletParams(businessData);
467
+ const customerId = Number(walletParams.customer_id || 0);
468
+ const requestParams = {
469
+ ids: selectedIds.map((id) => String(id)),
470
+ exact_codes: this.getSearchedWalletAssetCodes(),
471
+ order_product_amount: walletParams.order_product_amount,
472
+ order_expect_amount: walletParams.order_expect_amount,
473
+ order_wait_pay_amount: walletParams.order_wait_pay_amount,
474
+ products: walletParams.products,
475
+ available: 2,
476
+ filter_prepare_wallet_pass: 1,
477
+ sale_channel: walletParams.sale_channel || "pos"
478
+ };
479
+ if (customerId > 1) {
480
+ requestParams.customer_id = customerId;
481
+ }
482
+ const response = await this.paymentModule.request.post(
483
+ "/machinecode/prepare/deduction/aggregate-recalculate",
484
+ requestParams
485
+ );
486
+ const responseData = response == null ? void 0 : response.data;
487
+ const hasAggregateLists = responseData && (Object.prototype.hasOwnProperty.call(
488
+ responseData,
489
+ "recalculate_list"
490
+ ) || Object.prototype.hasOwnProperty.call(
491
+ responseData,
492
+ "customer_wallet_pass_list"
493
+ ));
494
+ if (!hasAggregateLists) {
495
+ throw new Error("WalletPass aggregate response is missing list data");
496
+ }
497
+ const recalculateList = Array.isArray(responseData == null ? void 0 : responseData.recalculate_list) ? responseData.recalculate_list : [];
498
+ const customerWalletPassList = Array.isArray(
499
+ responseData == null ? void 0 : responseData.customer_wallet_pass_list
500
+ ) ? responseData.customer_wallet_pass_list : [];
501
+ const allList = mergeWalletAssets(
502
+ recalculateList,
503
+ customerWalletPassList
504
+ );
505
+ const walletPassEvaluator = (_b = (_a = this.paymentModule.window) == null ? void 0 : _a.getWalletPassEvaluator) == null ? void 0 : _b.call(_a);
506
+ const evaluated = (walletPassEvaluator == null ? void 0 : walletPassEvaluator.getRecommendedVouchers) ? walletPassEvaluator.getRecommendedVouchers({
507
+ orderTotalAmount: walletParams.order_wait_pay_amount,
508
+ products: walletParams.products,
509
+ vouchers: allList
510
+ }) : {
511
+ recommended: [],
512
+ transformList: allList.filter(isWalletAssetAvailable),
513
+ noApplicableVoucher: allList.filter(
514
+ (item) => !isWalletAssetAvailable(item)
515
+ )
516
+ };
517
+ const returnedSelectedKeys = new Set(
518
+ recalculateList.filter(isWalletAssetAvailable).map((item) => getWalletAssetKey(item))
519
+ );
520
+ const authoritativeSelectedIds = selectedIds.filter(
521
+ (id) => returnedSelectedKeys.has(String(id))
522
+ );
523
+ this.walletRecommendList = evaluated.recommended || [];
524
+ this.userIdentificationCodes = allList;
525
+ this.emitEvent(import_types.WalletPassHooks.OnUserIdentificationCodesUpdated, {
526
+ userIdentificationCodes: this.userIdentificationCodes
527
+ });
528
+ this.walletInitData = {
529
+ transformList: evaluated.transformList || [],
530
+ noApplicableVoucher: evaluated.noApplicableVoucher || [],
531
+ products: walletParams.products || []
532
+ };
533
+ this.paymentModule.logInfo(
534
+ "[WalletPass] 聚合重算 WalletPass 完成",
535
+ {
536
+ selected_count: recalculateList.length,
537
+ remaining_count: customerWalletPassList.length,
538
+ searched_codes_count: requestParams.exact_codes.length
539
+ }
540
+ );
541
+ return {
542
+ walletRecommendList: this.walletRecommendList,
543
+ userIdentificationCodes: this.userIdentificationCodes,
544
+ transformList: evaluated.transformList || [],
545
+ noApplicableVoucher: evaluated.noApplicableVoucher || [],
546
+ products: walletParams.products || [],
547
+ authoritativeSelectedIds
548
+ };
549
+ }
471
550
  async getWalletPassRecommendListAsync(params) {
472
551
  var _a;
473
552
  try {
@@ -681,6 +760,7 @@ var WalletPassPaymentImpl = class {
681
760
  * 推荐结果只作为可用性/金额计算输入,不会自动成为 selectedIds。
682
761
  */
683
762
  async refreshWalletAssetsFromBusinessAsync(businessData, options = {}) {
763
+ var _a;
684
764
  const requestSequence = ++this.walletAssetsRequestSequence;
685
765
  const nextCustomerId = businessData.customer_id;
686
766
  const previousCustomerId = this.walletAssetsState.customerId;
@@ -697,6 +777,44 @@ var WalletPassPaymentImpl = class {
697
777
  );
698
778
  const selectedIds = preserveSelection ? [...this.walletAssetsState.selectedIds] : [];
699
779
  const selectionSources = preserveSelection ? { ...this.walletAssetsState.selectionSources } : {};
780
+ if (!((_a = businessData.products) == null ? void 0 : _a.length)) {
781
+ this.generateWalletParams(businessData);
782
+ const restoredSearchedAssets = this.searchResults.filter(isWalletPaymentAsset).map((item) => ({
783
+ ...item,
784
+ actualDeduction: 0,
785
+ deductionDetails: [],
786
+ _available_max_amount: 0,
787
+ _unified_available_status: 0,
788
+ _wallet_asset_recommended: false
789
+ }));
790
+ this.walletRecommendList = [];
791
+ this.userIdentificationCodes = [];
792
+ this.walletInitData = {
793
+ transformList: [],
794
+ noApplicableVoucher: restoredSearchedAssets,
795
+ products: []
796
+ };
797
+ this.walletAssetsCalculationContext = {
798
+ orderTotalAmount: 0,
799
+ products: []
800
+ };
801
+ this.emitEvent(import_types.WalletPassHooks.OnUserIdentificationCodesUpdated, {
802
+ userIdentificationCodes: []
803
+ });
804
+ return this.publishWalletAssetsState({
805
+ status: "ready",
806
+ customerId: nextCustomerId,
807
+ items: mergeWalletAssets(
808
+ restoredSearchedAssets,
809
+ committedItems
810
+ ),
811
+ selectedIds: [],
812
+ selectedItems: [],
813
+ selectionSources: {},
814
+ totalSelectedAmount: 0,
815
+ error: null
816
+ });
817
+ }
700
818
  this.publishWalletAssetsState({
701
819
  status: "loading",
702
820
  customerId: nextCustomerId,
@@ -708,9 +826,13 @@ var WalletPassPaymentImpl = class {
708
826
  error: null
709
827
  });
710
828
  try {
711
- const result = await this.initializeWalletDataFromBusinessAsync(
712
- businessData
713
- );
829
+ const searchedWalletAssetCodes = preserveSelection ? this.getSearchedWalletAssetCodes() : [];
830
+ const useAggregateRecalculate = preserveSelection && (selectedIds.length > 0 || searchedWalletAssetCodes.length > 0);
831
+ const aggregateResult = useAggregateRecalculate ? await this.aggregateRecalculateWalletAssetsAsync(
832
+ businessData,
833
+ selectedIds
834
+ ) : null;
835
+ const result = aggregateResult || await this.initializeWalletDataFromBusinessAsync(businessData);
714
836
  if (requestSequence !== this.walletAssetsRequestSequence) {
715
837
  return this.getWalletAssetsState();
716
838
  }
@@ -718,7 +840,27 @@ var WalletPassPaymentImpl = class {
718
840
  orderTotalAmount: Number(businessData.order_wait_pay_amount || 0),
719
841
  products: result.products || businessData.products || []
720
842
  };
721
- const searchedWalletAssets = preserveSelection ? await this.revalidateSearchedWalletAssets(requestSequence) : [];
843
+ const authoritativeSelectedIds = (aggregateResult == null ? void 0 : aggregateResult.authoritativeSelectedIds) || selectedIds;
844
+ if (aggregateResult) {
845
+ const returnedAggregateKeys = new Set(
846
+ [
847
+ ...result.transformList || [],
848
+ ...result.noApplicableVoucher || []
849
+ ].map((item) => getWalletAssetKey(item))
850
+ );
851
+ const missingSelectedKeys = new Set(
852
+ selectedIds.map((id) => String(id)).filter((id) => !returnedAggregateKeys.has(id))
853
+ );
854
+ if (missingSelectedKeys.size > 0) {
855
+ this.searchResults = this.searchResults.filter(
856
+ (item) => !missingSelectedKeys.has(getWalletAssetKey(item))
857
+ );
858
+ }
859
+ }
860
+ const searchedWalletAssets = preserveSelection ? this.syncSearchedWalletAssets([
861
+ ...result.transformList || [],
862
+ ...result.noApplicableVoucher || []
863
+ ]) : [];
722
864
  if (requestSequence !== this.walletAssetsRequestSequence) {
723
865
  return this.getWalletAssetsState();
724
866
  }
@@ -728,7 +870,7 @@ var WalletPassPaymentImpl = class {
728
870
  )
729
871
  );
730
872
  const items = mergeWalletAssets(
731
- preserveSelection ? this.walletAssetsState.selectedItems : [],
873
+ preserveSelection && !aggregateResult ? this.walletAssetsState.selectedItems : [],
732
874
  searchedWalletAssets,
733
875
  result.transformList || [],
734
876
  result.noApplicableVoucher || []
@@ -738,7 +880,7 @@ var WalletPassPaymentImpl = class {
738
880
  getWalletAssetKey(asset)
739
881
  )
740
882
  }));
741
- const latestSelectedIds = preserveSelection ? [...this.walletAssetsState.selectedIds] : [];
883
+ const latestSelectedIds = preserveSelection ? authoritativeSelectedIds : [];
742
884
  const latestSelectionSources = preserveSelection ? { ...this.walletAssetsState.selectionSources } : {};
743
885
  return this.recalculateWalletAssets(
744
886
  items,
@@ -749,6 +891,15 @@ var WalletPassPaymentImpl = class {
749
891
  if (requestSequence !== this.walletAssetsRequestSequence) {
750
892
  return this.getWalletAssetsState();
751
893
  }
894
+ this.paymentModule.logError(
895
+ "[WalletPass] 刷新共享钱包资产失败,保留刷新前状态",
896
+ error,
897
+ {
898
+ customer_id: businessData.customer_id,
899
+ selected_ids: selectedIds,
900
+ searched_codes: this.getSearchedWalletAssetCodes()
901
+ }
902
+ );
752
903
  return this.publishWalletAssetsState({
753
904
  status: "error",
754
905
  items: preserveSelection ? this.walletAssetsState.items : committedItems,
@@ -841,6 +992,17 @@ var WalletPassPaymentImpl = class {
841
992
  state: this.getWalletAssetsState()
842
993
  };
843
994
  }
995
+ const selectedAsset = this.walletAssetsState.selectedItems.find(
996
+ (asset2) => matchesWalletAssetCode(asset2, normalizedCode)
997
+ );
998
+ if (selectedAsset) {
999
+ return {
1000
+ type: "normalCode",
1001
+ asset: selectedAsset,
1002
+ selected: true,
1003
+ state: this.getWalletAssetsState()
1004
+ };
1005
+ }
844
1006
  this.walletAssetsRequestSequence += 1;
845
1007
  const result = await this.searchIdentificationCodeAsync({
846
1008
  ...this.walletParams || {},
@@ -193,6 +193,7 @@ export interface ProductData {
193
193
  status?: string;
194
194
  required?: number | string | boolean;
195
195
  resource_id?: number | string | null;
196
+ [key: string]: any;
196
197
  };
197
198
  /** 组合商品id,动态附加 */
198
199
  product_variant_id?: number;
@@ -106,39 +106,48 @@ var ProductList = class extends import_BaseModule.BaseModule {
106
106
  } catch (error) {
107
107
  console.error(error);
108
108
  }
109
+ const channelMap = {
110
+ online_store: "online-store",
111
+ scan_to_order: "online-store",
112
+ "scan-to-order": "online-store",
113
+ scan_to_order_2: "mobile_order",
114
+ scan_to_order_3: "scantoorder3"
115
+ };
116
+ const rawApplicationCode = (_b = this.otherParams) == null ? void 0 : _b.channel;
117
+ const mappedApplicationCode = typeof rawApplicationCode === "string" ? channelMap[rawApplicationCode] || rawApplicationCode : rawApplicationCode;
118
+ const queryPayload = {
119
+ open_quotation: 1,
120
+ open_bundle: 0,
121
+ exclude_extension_type: [
122
+ "product_party",
123
+ "product_event",
124
+ "product_series_event",
125
+ "product_package_ticket",
126
+ "ticket",
127
+ "event_item"
128
+ ],
129
+ with: ["category", "collection", "resourceRelation"],
130
+ status,
131
+ num: 500,
132
+ skip: 1,
133
+ customer_id,
134
+ ...Array.isArray(category_ids) && category_ids.length ? { category_ids } : {},
135
+ ...Array.isArray(product_ids) && product_ids.length ? { ids: product_ids } : {},
136
+ ...Array.isArray(collection) && collection.length ? { collection } : {},
137
+ front_end_cache_id: cacheId,
138
+ ...Array.isArray(menu_list_ids) && menu_list_ids.length ? { menu_list_ids } : {},
139
+ with_count,
140
+ // client_schedule_ids: schedule_ids,
141
+ schedule_date,
142
+ application_code: mappedApplicationCode,
143
+ is_eject: 1,
144
+ with_schedule,
145
+ schedule_datetime,
146
+ extension_type
147
+ };
109
148
  const productsData = await this.request.post(
110
149
  `/product/query`,
111
- {
112
- open_quotation: 1,
113
- open_bundle: 0,
114
- exclude_extension_type: [
115
- "product_party",
116
- "product_event",
117
- "product_series_event",
118
- "product_package_ticket",
119
- "ticket",
120
- "event_item"
121
- ],
122
- with: ["category", "collection", "resourceRelation"],
123
- status,
124
- num: 500,
125
- skip: 1,
126
- customer_id,
127
- category_ids,
128
- ids: product_ids,
129
- collection,
130
- front_end_cache_id: cacheId,
131
- menu_list_ids,
132
- with_count,
133
- // client_schedule_ids: schedule_ids,
134
- schedule_date,
135
- application_code: (_b = this.otherParams) == null ? void 0 : _b.channel,
136
- is_eject: 1,
137
- with_schedule,
138
- schedule_datetime,
139
- extension_type,
140
- strategy_context
141
- },
150
+ queryPayload,
142
151
  { osServer: true, callback: options == null ? void 0 : options.callback, subscriberId: options == null ? void 0 : options.subscriberId, customToast: () => {
143
152
  } }
144
153
  );
@@ -21,7 +21,7 @@ export declare class QuotationModule extends BaseModule implements Module {
21
21
  * Look up the quotation price for a specific product (+ optional variant) at a given datetime.
22
22
  * Returns the price as a string (e.g. "300.00"), or null if no quotation applies.
23
23
  *
24
- * Priority: iterates quotations already sorted by `sort` ascending (lowest = highest priority).
24
+ * Priority: iterates quotations already sorted by `sort` descending (highest = highest priority).
25
25
  * First matching quotation whose schedule covers `datetime` and whose product_data contains
26
26
  * the requested productId wins.
27
27
  */
@@ -52,7 +52,7 @@ var QuotationModule = class extends import_BaseModule.BaseModule {
52
52
  { useCache: false, osServer: true }
53
53
  );
54
54
  const list = ((_a = res == null ? void 0 : res.data) == null ? void 0 : _a.list) || (res == null ? void 0 : res.list) || [];
55
- list.sort((a, b) => a.sort - b.sort);
55
+ list.sort((a, b) => b.sort - a.sort);
56
56
  this.store.list = list;
57
57
  }
58
58
  getQuotationList() {
@@ -96,7 +96,7 @@ var QuotationModule = class extends import_BaseModule.BaseModule {
96
96
  * Look up the quotation price for a specific product (+ optional variant) at a given datetime.
97
97
  * Returns the price as a string (e.g. "300.00"), or null if no quotation applies.
98
98
  *
99
- * Priority: iterates quotations already sorted by `sort` ascending (lowest = highest priority).
99
+ * Priority: iterates quotations already sorted by `sort` descending (highest = highest priority).
100
100
  * First matching quotation whose schedule covers `datetime` and whose product_data contains
101
101
  * the requested productId wins.
102
102
  */
@@ -0,0 +1,24 @@
1
+ import { BaseModule } from '../BaseModule';
2
+ import type { Module, ModuleOptions, PisellCore } from '../../types';
3
+ import type { ResourcePlannerAssignmentResult, ResourcePlannerAssignableSlotResult, ResourcePlannerContextInput, ResourcePlannerProjection, ResourcePlannerQuery, ResourcePlannerSelectionPatch, ResourcePlannerSnapshot, ResourcePlannerValidationResult } from './types';
4
+ export * from './types';
5
+ export * from './planner';
6
+ export declare enum ResourcePlannerHooks {
7
+ onContextChanged = "resourcePlanner:onContextChanged",
8
+ onSelectionChanged = "resourcePlanner:onSelectionChanged",
9
+ onProjectionChanged = "resourcePlanner:onProjectionChanged"
10
+ }
11
+ export declare class ResourcePlannerModule extends BaseModule implements Module {
12
+ protected defaultName: string;
13
+ protected defaultVersion: string;
14
+ private store;
15
+ initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
16
+ setContext(input: ResourcePlannerContextInput): ResourcePlannerSnapshot;
17
+ mergeContext(input: ResourcePlannerContextInput): ResourcePlannerSnapshot;
18
+ setSelectionPatch(patch: ResourcePlannerSelectionPatch): ResourcePlannerSnapshot;
19
+ queryAvailability(query?: ResourcePlannerQuery): ResourcePlannerProjection;
20
+ autoAssign(query?: ResourcePlannerQuery): ResourcePlannerAssignmentResult;
21
+ resolveAssignableSlots(query?: ResourcePlannerQuery): ResourcePlannerAssignableSlotResult;
22
+ validateSelection(): ResourcePlannerValidationResult;
23
+ getSnapshot(): ResourcePlannerSnapshot;
24
+ }