@pisell/pisellos 2.3.60 → 2.3.62

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.
@@ -214,7 +214,6 @@ var WalletPassEvaluator = class {
214
214
  }
215
215
  const rawText = this.getText(reasonCode);
216
216
  const currency = failedField && AMOUNT_FIELDS.has(failedField) ? ((_g = (_f = this.otherParams) == null ? void 0 : _f.getData) == null ? void 0 : _g.call(_f, "shop_symbol")) || "" : "";
217
- console.log(currency, "currency12345");
218
217
  const reason = thresholdValue !== void 0 ? formatReason(rawText, thresholdValue, currency) : rawText;
219
218
  results.push({
220
219
  voucher,
@@ -26,6 +26,11 @@ export interface Voucher {
26
26
  recommended_usage_amount: number;
27
27
  /** 后端计算推荐使用金额(仅商品) 不包含税费附加费 */
28
28
  recommended_pure_product_usage_amount: number;
29
+ /**
30
+ * 扫码资产自身可供前端重新计算的金额基准。
31
+ * 后端 recommended_usage_amount 会包含当前已选券上下文,取消勾选后不能继续把它当作资产永久上限。
32
+ */
33
+ _wallet_asset_recalculation_base_amount?: number;
29
34
  /** 实际抵扣金额 */
30
35
  actualDeduction: number;
31
36
  /** 抵扣详情 */
@@ -43,6 +43,21 @@ __export(utils_exports, {
43
43
  });
44
44
  module.exports = __toCommonJS(utils_exports);
45
45
  var import_decimal = __toESM(require("decimal.js"));
46
+ var DEFAULT_WALLET_PASS_CALCULATION_CONFIG = {
47
+ maxDeductionAmount: 99999,
48
+ maxUsagePerOrder: 0,
49
+ allowCrossProduct: true,
50
+ applicableProductLimit: 0,
51
+ deductTaxAndFee: true,
52
+ maxPassesPerItem: 0,
53
+ deductOptionPrice: false
54
+ };
55
+ function getWalletPassCalculationConfig(voucher) {
56
+ return {
57
+ ...DEFAULT_WALLET_PASS_CALCULATION_CONFIG,
58
+ ...(voucher == null ? void 0 : voucher.config) || {}
59
+ };
60
+ }
46
61
  var getProductQuantity = (product) => {
47
62
  return product.quantity || product.product_quantity || 1;
48
63
  };
@@ -105,9 +120,15 @@ function applyMaxPassUsageIncrements(usageMap, walletPassProductId, maxPassesPer
105
120
  });
106
121
  }
107
122
  var getRecommendedAmount = (voucher) => {
108
- console.log("voucher312", voucher);
109
123
  const { config, recommended_usage_amount, recommended_pure_product_usage_amount } = voucher;
110
124
  const deductTaxAndFee = (config == null ? void 0 : config.deductTaxAndFee) ?? true;
125
+ const rawRecalculationBaseAmount = voucher._wallet_asset_recalculation_base_amount;
126
+ if (rawRecalculationBaseAmount !== void 0 && rawRecalculationBaseAmount !== null) {
127
+ const recalculationBaseAmount = Number(rawRecalculationBaseAmount);
128
+ if (Number.isFinite(recalculationBaseAmount) && recalculationBaseAmount >= 0) {
129
+ return recalculationBaseAmount;
130
+ }
131
+ }
111
132
  return deductTaxAndFee ? recommended_usage_amount : recommended_pure_product_usage_amount ?? recommended_usage_amount;
112
133
  };
113
134
  var getApplicableProductIds = (voucher) => {
@@ -218,7 +239,7 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
218
239
  return import_decimal.default.min(baseAmount, finalApplicableAmount, remainingOrderAmount);
219
240
  };
220
241
  const isVoucherAvailable = (voucher, productsData, usedVoucherCounts2, itemPassUsage) => {
221
- const { config, id, product_id } = voucher;
242
+ const { config, product_id } = voucher;
222
243
  const recommendedAmount = getRecommendedAmount(voucher);
223
244
  if (recommendedAmount <= 0) {
224
245
  return { isAvailable: false, reasonCode: "not_meet_the_required_conditions" };
@@ -453,6 +474,7 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
453
474
  const productsForCalc = expandProductsWithBundleItems(products, true);
454
475
  let remainingOrderAmount = new import_decimal.default(orderTotalAmount);
455
476
  const selectedWithDetails = [];
477
+ const usedVoucherCounts = /* @__PURE__ */ new Map();
456
478
  const itemPassUsageMap = /* @__PURE__ */ new Map();
457
479
  const getItemPassUsageRecalc = (walletPassProductId, lineKey) => {
458
480
  var _a;
@@ -469,8 +491,29 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
469
491
  });
470
492
  };
471
493
  selectedVouchers.forEach((selectedVoucher) => {
472
- const { config, id } = selectedVoucher;
473
- const { maxDeductionAmount, allowCrossProduct, applicableProductLimit, deductTaxAndFee = true, maxPassesPerItem = 0 } = config;
494
+ const { product_id } = selectedVoucher;
495
+ const config = getWalletPassCalculationConfig(selectedVoucher);
496
+ const {
497
+ maxDeductionAmount,
498
+ maxUsagePerOrder,
499
+ allowCrossProduct,
500
+ applicableProductLimit,
501
+ deductTaxAndFee,
502
+ maxPassesPerItem
503
+ } = config;
504
+ const usedCount = usedVoucherCounts.get(product_id) || 0;
505
+ if (maxUsagePerOrder > 0 && usedCount >= maxUsagePerOrder) {
506
+ selectedWithDetails.push({
507
+ ...selectedVoucher,
508
+ config,
509
+ actualDeduction: 0,
510
+ deductionDetails: [],
511
+ _available_max_amount: 0,
512
+ _unified_available_status: 0,
513
+ reasonCode: "usage_limit_reached"
514
+ });
515
+ return;
516
+ }
474
517
  const unitPriceField = deductTaxAndFee ? "unitPriceWithTax" : "unitPricePure";
475
518
  const amountField = deductTaxAndFee ? "remainingAmountWithTax" : "remainingAmountPure";
476
519
  let applicableProducts = getApplicableProducts(
@@ -481,6 +524,7 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
481
524
  if (applicableProducts.length === 0) {
482
525
  selectedWithDetails.push({
483
526
  ...selectedVoucher,
527
+ config,
484
528
  actualDeduction: 0,
485
529
  deductionDetails: [],
486
530
  _available_max_amount: 0,
@@ -558,6 +602,7 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
558
602
  applyMaxPassUsageIncrements(itemPassUsageMap, selectedVoucher.product_id, maxPassesPerItem, deductionDetails);
559
603
  selectedWithDetails.push({
560
604
  ...selectedVoucher,
605
+ config,
561
606
  actualDeduction: totalDeducted.toNumber(),
562
607
  // 转换为数字
563
608
  deductionDetails,
@@ -565,12 +610,11 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
565
610
  // 转换为数字
566
611
  _unified_available_status: totalDeducted.greaterThan(0) ? 1 : 0
567
612
  });
613
+ if (totalDeducted.greaterThan(0)) {
614
+ usedVoucherCounts.set(product_id, usedCount + 1);
615
+ }
568
616
  });
569
617
  const selectedIds = new Set(selectedVouchers.map((v) => v.id));
570
- const usedVoucherCounts = /* @__PURE__ */ new Map();
571
- selectedVouchers.forEach((v) => {
572
- usedVoucherCounts.set(v.product_id, (usedVoucherCounts.get(v.product_id) || 0) + 1);
573
- });
574
618
  const allWithUpdatedStatus = allVouchers.map((voucher) => {
575
619
  if (selectedIds.has(voucher.id)) {
576
620
  const selectedDetail = selectedWithDetails.find(
@@ -578,8 +622,15 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
578
622
  );
579
623
  return selectedDetail || voucher;
580
624
  }
581
- const { config, id, product_id } = voucher;
582
- const { maxDeductionAmount, allowCrossProduct, applicableProductLimit, deductTaxAndFee = true, maxPassesPerItem = 0 } = config;
625
+ const { product_id } = voucher;
626
+ const config = getWalletPassCalculationConfig(voucher);
627
+ const {
628
+ maxDeductionAmount,
629
+ allowCrossProduct,
630
+ applicableProductLimit,
631
+ deductTaxAndFee,
632
+ maxPassesPerItem
633
+ } = config;
583
634
  const unitPriceField = deductTaxAndFee ? "unitPriceWithTax" : "unitPricePure";
584
635
  const amountField = deductTaxAndFee ? "remainingAmountWithTax" : "remainingAmountPure";
585
636
  const recommendedAmount = getRecommendedAmount(voucher);
@@ -663,6 +714,7 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
663
714
  }
664
715
  return {
665
716
  ...voucher,
717
+ config,
666
718
  _available_max_amount: calculatedMaxAmount.toNumber(),
667
719
  // 转换为数字
668
720
  _unified_available_status: isAvailable ? 1 : 0,
@@ -486,6 +486,8 @@ export interface WalletPassPayment {
486
486
  importWalletAssetsSnapshot: (snapshot: WalletAssetsSnapshot) => WalletAssetsState;
487
487
  /** 设置单张钱包资产的选择状态并重新计算其实际抵扣额。 */
488
488
  selectWalletAsset: (assetId: WalletAssetId, options: SelectWalletAssetOptions) => WalletAssetsState;
489
+ /** 更新已选钱包资产的手动使用金额,并保持原有选择顺序重新计算。 */
490
+ updateWalletAssetAmount: (assetId: WalletAssetId, amount: number) => WalletAssetsState;
489
491
  /** 精确搜索钱包资产;仅当前券可用时自动选择。 */
490
492
  scanWalletAssetAsync: (code: string) => Promise<ScanWalletAssetResult>;
491
493
  /** 清空未确认的钱包资产选择。 */
@@ -34,7 +34,11 @@ var formatWalletPassList2PreparePayments = (list) => {
34
34
  const formatted = (list || []).map((item) => {
35
35
  return {
36
36
  voucher_id: item.id || 0,
37
- amount: Number(item.edit_current_amount || getAvailableMaxAmount(item)) || 0,
37
+ // 前端策略重算后的 actualDeduction 才是最终可同步金额;
38
+ // edit_current_amount 只是用户请求值,仍可能被策略和订单剩余金额裁剪。
39
+ amount: Number(
40
+ item.actualDeduction ?? item.edit_current_amount ?? getAvailableMaxAmount(item)
41
+ ) || 0,
38
42
  tag: item.tag || "",
39
43
  wallet_pass_usage_unit: item.wallet_pass_usage_unit || {},
40
44
  wallet_pass_use_value: item.wallet_pass_use_value || void 0
@@ -24,6 +24,11 @@ export declare class WalletPassPaymentImpl implements WalletPassPayment {
24
24
  private emitEvent;
25
25
  private publishWalletAssetsState;
26
26
  private recalculateWalletAssets;
27
+ /**
28
+ * 搜索接口只返回后端 Wallet Pass 数据,不包含前端策略 config。
29
+ * 在资产进入共享选择状态前补齐策略结果,避免增量重算回退到接口状态。
30
+ */
31
+ private formatSearchedWalletPaymentAssets;
27
32
  /** 获取当前缓存中所有支付类 Wallet 资产的扫码 code。 */
28
33
  private getSearchedWalletAssetCodes;
29
34
  /**
@@ -106,7 +111,13 @@ export declare class WalletPassPaymentImpl implements WalletPassPayment {
106
111
  getWalletAssetsState(): WalletAssetsState;
107
112
  exportWalletAssetsSnapshot(): WalletAssetsSnapshot;
108
113
  importWalletAssetsSnapshot(snapshot: WalletAssetsSnapshot): WalletAssetsState;
114
+ private updateWalletAssetEditAmountInCaches;
109
115
  selectWalletAsset(assetId: WalletAssetId, options: SelectWalletAssetOptions): WalletAssetsState;
116
+ /**
117
+ * 更新已选资产的手动金额。只允许在当前实际抵扣额内向下调整,
118
+ * 金额为 0 时沿用 legacy 行为取消选择。
119
+ */
120
+ updateWalletAssetAmount(assetId: WalletAssetId, amount: number): WalletAssetsState;
110
121
  scanWalletAssetAsync(code: string): Promise<ScanWalletAssetResult>;
111
122
  clearWalletAssetSelection(): WalletAssetsState;
112
123
  setCommittedWalletAssets(committedIds: WalletAssetId[], committedAssets?: any[]): WalletAssetsState;
@@ -52,6 +52,25 @@ function normalizeWalletAssetCode(code) {
52
52
  function getWalletAssetCodeKeys(asset) {
53
53
  return [asset == null ? void 0 : asset.code, asset == null ? void 0 : asset.encoded].map(normalizeWalletAssetCode).filter(Boolean);
54
54
  }
55
+ function withWalletAssetRecalculationBaseAmount(asset) {
56
+ const existingBaseAmount = Number(
57
+ asset == null ? void 0 : asset._wallet_asset_recalculation_base_amount
58
+ );
59
+ if (Number.isFinite(existingBaseAmount) && existingBaseAmount >= 0) {
60
+ return asset;
61
+ }
62
+ if (!["product_voucher", "gift_card"].includes(asset == null ? void 0 : asset.tag)) {
63
+ return asset;
64
+ }
65
+ const balanceParValue = Number(asset == null ? void 0 : asset.balance_par_value);
66
+ if (!Number.isFinite(balanceParValue) || balanceParValue < 0) {
67
+ return asset;
68
+ }
69
+ return {
70
+ ...asset,
71
+ _wallet_asset_recalculation_base_amount: balanceParValue
72
+ };
73
+ }
55
74
  function isWalletAssetAvailable(asset) {
56
75
  if (!asset)
57
76
  return false;
@@ -222,6 +241,42 @@ var WalletPassPaymentImpl = class {
222
241
  error: null
223
242
  });
224
243
  }
244
+ /**
245
+ * 搜索接口只返回后端 Wallet Pass 数据,不包含前端策略 config。
246
+ * 在资产进入共享选择状态前补齐策略结果,避免增量重算回退到接口状态。
247
+ */
248
+ formatSearchedWalletPaymentAssets(assets) {
249
+ var _a, _b, _c, _d;
250
+ if (!assets.length)
251
+ return assets;
252
+ const assetsWithRecalculationBase = assets.map(
253
+ withWalletAssetRecalculationBaseAmount
254
+ );
255
+ const evaluator = (_b = (_a = this.paymentModule.window) == null ? void 0 : _a.getWalletPassEvaluator) == null ? void 0 : _b.call(_a);
256
+ if (!(evaluator == null ? void 0 : evaluator.searchVoucherFormat))
257
+ return assetsWithRecalculationBase;
258
+ const hasCalculationProducts = this.walletAssetsCalculationContext.products.length > 0;
259
+ const products = hasCalculationProducts ? this.walletAssetsCalculationContext.products : ((_c = this.walletParams) == null ? void 0 : _c.products) || [];
260
+ const orderTotalAmount = Number(
261
+ hasCalculationProducts ? this.walletAssetsCalculationContext.orderTotalAmount : ((_d = this.walletParams) == null ? void 0 : _d.order_wait_pay_amount) || 0
262
+ );
263
+ try {
264
+ const formattedAssets = evaluator.searchVoucherFormat({
265
+ orderTotalAmount,
266
+ products,
267
+ vouchers: assetsWithRecalculationBase
268
+ });
269
+ return formattedAssets;
270
+ } catch (error) {
271
+ this.paymentModule.logWarning(
272
+ "[WalletPass] 搜索资产策略格式化失败,保留接口结果",
273
+ {
274
+ error: error instanceof Error ? error.message : String(error)
275
+ }
276
+ );
277
+ return assetsWithRecalculationBase;
278
+ }
279
+ }
225
280
  /** 获取当前缓存中所有支付类 Wallet 资产的扫码 code。 */
226
281
  getSearchedWalletAssetCodes() {
227
282
  const cachedAssets = this.searchResults.filter(isWalletPaymentAsset);
@@ -245,11 +300,23 @@ var WalletPassPaymentImpl = class {
245
300
  );
246
301
  if (searchedCodeKeys.size === 0)
247
302
  return cachedAssets;
303
+ const cachedAssetByCode = /* @__PURE__ */ new Map();
304
+ cachedAssets.forEach((item) => {
305
+ getWalletAssetCodeKeys(item).forEach((code) => {
306
+ cachedAssetByCode.set(code, item);
307
+ });
308
+ });
248
309
  const refreshedAssets = refreshedCandidates.filter(
249
310
  (item) => isWalletPaymentAsset(item) && searchedCodeKeys.has(
250
311
  String((item == null ? void 0 : item.code) || "").trim().toUpperCase()
251
312
  )
252
- );
313
+ ).map((item) => {
314
+ const cachedAsset = getWalletAssetCodeKeys(item).map((code) => cachedAssetByCode.get(code)).find(Boolean);
315
+ return withWalletAssetRecalculationBaseAmount({
316
+ ...cachedAsset,
317
+ ...item
318
+ });
319
+ });
253
320
  if (refreshedAssets.length > 0) {
254
321
  const replacedCodes = new Set(
255
322
  refreshedAssets.map(
@@ -321,6 +388,10 @@ var WalletPassPaymentImpl = class {
321
388
  payment_order_id
322
389
  };
323
390
  this.walletParams = walletParams;
391
+ this.walletAssetsCalculationContext = {
392
+ orderTotalAmount: Number(walletParams.order_wait_pay_amount || 0),
393
+ products: Array.isArray(walletParams.products) ? walletParams.products : []
394
+ };
324
395
  this.paymentModule.logInfo("[WalletPass] 钱包默认参数已生成并存储", {
325
396
  customer_id: walletParams.customer_id,
326
397
  holder_id: walletParams.holder_id,
@@ -552,7 +623,7 @@ var WalletPassPaymentImpl = class {
552
623
  )
553
624
  };
554
625
  const returnedSelectedKeys = new Set(
555
- recalculateList.filter(isWalletAssetAvailable).map((item) => getWalletAssetKey(item))
626
+ allList.map((item) => getWalletAssetKey(item))
556
627
  );
557
628
  const authoritativeSelectedIds = selectedIds.filter(
558
629
  (id) => returnedSelectedKeys.has(String(id))
@@ -818,6 +889,17 @@ var WalletPassPaymentImpl = class {
818
889
  const assetId = getWalletAssetId(asset);
819
890
  return assetId !== void 0 && assetId !== null && selectionSources[String(assetId)] === "scan";
820
891
  }) : [];
892
+ const manualEditAmountByKey = /* @__PURE__ */ new Map();
893
+ if (preserveSelection) {
894
+ this.walletAssetsState.selectedItems.forEach((asset) => {
895
+ if (typeof (asset == null ? void 0 : asset.edit_current_amount) !== "number")
896
+ return;
897
+ manualEditAmountByKey.set(
898
+ getWalletAssetKey(asset),
899
+ asset.edit_current_amount
900
+ );
901
+ });
902
+ }
821
903
  if (!((_a = businessData.products) == null ? void 0 : _a.length)) {
822
904
  this.queuePendingAutoSelectForAssets(scanSelectedAssets);
823
905
  this.generateWalletParams(businessData);
@@ -916,12 +998,16 @@ var WalletPassPaymentImpl = class {
916
998
  searchedWalletAssets,
917
999
  result.transformList || [],
918
1000
  result.noApplicableVoucher || []
919
- ).map((asset) => ({
920
- ...asset,
921
- _wallet_asset_recommended: recommendedKeys.has(
922
- getWalletAssetKey(asset)
923
- )
924
- }));
1001
+ ).map((asset) => {
1002
+ const assetKey = getWalletAssetKey(asset);
1003
+ return {
1004
+ ...asset,
1005
+ ...manualEditAmountByKey.has(assetKey) ? {
1006
+ edit_current_amount: manualEditAmountByKey.get(assetKey)
1007
+ } : {},
1008
+ _wallet_asset_recommended: recommendedKeys.has(assetKey)
1009
+ };
1010
+ });
925
1011
  const latestSelectedIds = preserveSelection ? authoritativeSelectedIds : [];
926
1012
  const latestSelectionSources = preserveSelection ? { ...this.walletAssetsState.selectionSources } : {};
927
1013
  const pendingAutoSelectAssets = this.walletAssetsBehavior.autoSelectAfterSearch ? items.filter(
@@ -1035,6 +1121,13 @@ var WalletPassPaymentImpl = class {
1035
1121
  selectionSources: snapshot.state.selectionSources || {}
1036
1122
  });
1037
1123
  }
1124
+ updateWalletAssetEditAmountInCaches(assetKey, amount) {
1125
+ const updateAsset = (asset) => getWalletAssetKey(asset) === assetKey ? { ...asset, edit_current_amount: amount } : asset;
1126
+ this.searchResults = this.searchResults.map(
1127
+ updateAsset
1128
+ );
1129
+ return this.walletAssetsState.items.map(updateAsset);
1130
+ }
1038
1131
  selectWalletAsset(assetId, options) {
1039
1132
  const assetKey = String(assetId);
1040
1133
  const asset = this.walletAssetsState.items.find(
@@ -1050,6 +1143,7 @@ var WalletPassPaymentImpl = class {
1050
1143
  );
1051
1144
  const selectionSources = { ...this.walletAssetsState.selectionSources };
1052
1145
  delete selectionSources[assetKey];
1146
+ let nextItems = this.walletAssetsState.items;
1053
1147
  if (options.selected) {
1054
1148
  if (!asset || !isWalletAssetAvailable(asset)) {
1055
1149
  return this.getWalletAssetsState();
@@ -1058,9 +1152,13 @@ var WalletPassPaymentImpl = class {
1058
1152
  selectionSources[assetKey] = options.source || "manual";
1059
1153
  } else if (asset) {
1060
1154
  this.clearPendingAutoSelectForAsset(asset);
1155
+ nextItems = this.updateWalletAssetEditAmountInCaches(
1156
+ assetKey,
1157
+ void 0
1158
+ );
1061
1159
  }
1062
1160
  const nextState = this.recalculateWalletAssets(
1063
- this.walletAssetsState.items,
1161
+ nextItems,
1064
1162
  selectedIds,
1065
1163
  selectionSources
1066
1164
  );
@@ -1069,6 +1167,54 @@ var WalletPassPaymentImpl = class {
1069
1167
  }
1070
1168
  return nextState;
1071
1169
  }
1170
+ /**
1171
+ * 更新已选资产的手动金额。只允许在当前实际抵扣额内向下调整,
1172
+ * 金额为 0 时沿用 legacy 行为取消选择。
1173
+ */
1174
+ updateWalletAssetAmount(assetId, amount) {
1175
+ const assetKey = String(assetId);
1176
+ const committedKeys = new Set(
1177
+ this.walletAssetsState.committedIds.map((id) => String(id))
1178
+ );
1179
+ const selectedKeys = new Set(
1180
+ this.walletAssetsState.selectedIds.map((id) => String(id))
1181
+ );
1182
+ const asset = this.walletAssetsState.items.find(
1183
+ (item) => getWalletAssetKey(item) === assetKey
1184
+ );
1185
+ const requestedAmount = Number(amount);
1186
+ if (!asset || committedKeys.has(assetKey) || !selectedKeys.has(assetKey) || !Number.isFinite(requestedAmount) || requestedAmount < 0) {
1187
+ return this.getWalletAssetsState();
1188
+ }
1189
+ const selectedIds = [...this.walletAssetsState.selectedIds];
1190
+ const selectionSources = { ...this.walletAssetsState.selectionSources };
1191
+ if (requestedAmount === 0) {
1192
+ const nextItems2 = this.updateWalletAssetEditAmountInCaches(
1193
+ assetKey,
1194
+ void 0
1195
+ );
1196
+ delete selectionSources[assetKey];
1197
+ this.clearPendingAutoSelectForAsset(asset);
1198
+ return this.recalculateWalletAssets(
1199
+ nextItems2,
1200
+ selectedIds.filter((id) => String(id) !== assetKey),
1201
+ selectionSources
1202
+ );
1203
+ }
1204
+ const currentDeductionAmount = getWalletAssetDeductionAmount(asset);
1205
+ const editAmount = Math.min(requestedAmount, currentDeductionAmount);
1206
+ if (editAmount <= 0)
1207
+ return this.getWalletAssetsState();
1208
+ const nextItems = this.updateWalletAssetEditAmountInCaches(
1209
+ assetKey,
1210
+ editAmount
1211
+ );
1212
+ return this.recalculateWalletAssets(
1213
+ nextItems,
1214
+ selectedIds,
1215
+ selectionSources
1216
+ );
1217
+ }
1072
1218
  async scanWalletAssetAsync(code) {
1073
1219
  const normalizedCode = String(code || "").trim();
1074
1220
  if (!normalizedCode) {
@@ -1097,7 +1243,15 @@ var WalletPassPaymentImpl = class {
1097
1243
  this.walletAssetsState.selectedItems
1098
1244
  )
1099
1245
  });
1100
- const paymentAssets = result.data.filter(isWalletPaymentAsset);
1246
+ const paymentAssets = this.formatSearchedWalletPaymentAssets(
1247
+ result.data.filter(isWalletPaymentAsset)
1248
+ );
1249
+ if (paymentAssets.length > 0) {
1250
+ this.searchResults = mergeWalletAssets(
1251
+ this.searchResults,
1252
+ paymentAssets
1253
+ );
1254
+ }
1101
1255
  const asset = paymentAssets.find(
1102
1256
  (item) => String((item == null ? void 0 : item.code) || "") === normalizedCode
1103
1257
  ) || paymentAssets[0];
@@ -1116,30 +1270,44 @@ var WalletPassPaymentImpl = class {
1116
1270
  this.walletAssetsState.selectionSources
1117
1271
  );
1118
1272
  const assetId = getWalletAssetId(asset);
1119
- const selected = this.walletAssetsBehavior.autoSelectAfterSearch && assetId !== void 0 && isWalletAssetAvailable(asset) ? this.selectWalletAsset(assetId, {
1273
+ const recalculatedAsset = assetId === void 0 ? void 0 : recalculatedState.items.find(
1274
+ (item) => getWalletAssetKey(item) === String(assetId)
1275
+ );
1276
+ const selected = this.walletAssetsBehavior.autoSelectAfterSearch && assetId !== void 0 && isWalletAssetAvailable(recalculatedAsset) ? this.selectWalletAsset(assetId, {
1120
1277
  selected: true,
1121
1278
  source: "scan"
1122
1279
  }) : recalculatedState;
1123
1280
  const isSelected = assetId !== void 0 && selected.selectedIds.some((id) => String(id) === String(assetId));
1281
+ const selectedStateAsset = assetId === void 0 ? void 0 : selected.items.find(
1282
+ (item) => getWalletAssetKey(item) === String(assetId)
1283
+ );
1284
+ const resolvedAsset = selectedStateAsset || recalculatedAsset || asset;
1124
1285
  if (isSelected) {
1125
- this.clearPendingAutoSelectForAsset(asset);
1286
+ this.clearPendingAutoSelectForAsset(resolvedAsset);
1126
1287
  } else if (this.walletAssetsBehavior.autoSelectAfterSearch) {
1127
1288
  this.pendingAutoSelectSearchCodes.add(
1128
1289
  normalizeWalletAssetCode(normalizedCode)
1129
1290
  );
1130
- this.queuePendingAutoSelectForAssets([asset]);
1291
+ this.queuePendingAutoSelectForAssets([resolvedAsset]);
1131
1292
  }
1132
1293
  return {
1133
1294
  type: result.type,
1134
- asset,
1295
+ asset: resolvedAsset,
1135
1296
  selected: isSelected,
1136
1297
  state: selected
1137
1298
  };
1138
1299
  }
1139
1300
  clearWalletAssetSelection() {
1140
1301
  this.pendingAutoSelectSearchCodes.clear();
1302
+ const selectedKeys = new Set(
1303
+ this.walletAssetsState.selectedIds.map((id) => String(id))
1304
+ );
1305
+ const clearSelectedEditAmount = (asset) => selectedKeys.has(getWalletAssetKey(asset)) ? { ...asset, edit_current_amount: void 0 } : asset;
1306
+ this.searchResults = this.searchResults.map(
1307
+ clearSelectedEditAmount
1308
+ );
1141
1309
  return this.recalculateWalletAssets(
1142
- this.walletAssetsState.items,
1310
+ this.walletAssetsState.items.map(clearSelectedEditAmount),
1143
1311
  [],
1144
1312
  {}
1145
1313
  );
@@ -151,7 +151,8 @@ var ProductList = class extends import_BaseModule.BaseModule {
151
151
  is_eject: 1,
152
152
  with_schedule,
153
153
  schedule_datetime,
154
- extension_type
154
+ extension_type,
155
+ strategy_context
155
156
  };
156
157
  const productsData = await this.request.post(
157
158
  `/product/query`,
@@ -362,6 +362,11 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
362
362
  selected: boolean;
363
363
  source?: WalletAssetSelectionSource;
364
364
  }): Promise<WalletAssetsState>;
365
+ /** 更新已选钱包资产的手动使用金额,并同步 pending payment。 */
366
+ updateWalletAssetAmount(params: {
367
+ assetId: WalletAssetId;
368
+ amount: number;
369
+ }): Promise<WalletAssetsState>;
365
370
  /** 扫码精确查券;仅可用资产会被自动选中。 */
366
371
  scanWalletAsset(code: string): Promise<ScanWalletAssetResult>;
367
372
  /** 清空全部未确认钱包选择,已支付钱包项由 Order 模块继续保留。 */
@@ -2657,6 +2657,17 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
2657
2657
  await this.syncSelectedWalletAssets(state);
2658
2658
  return this.publishWalletAssetsState(state);
2659
2659
  }
2660
+ /** 更新已选钱包资产的手动使用金额,并同步 pending payment。 */
2661
+ async updateWalletAssetAmount(params) {
2662
+ if (!this.store.payment)
2663
+ throw new Error("payment 模块未初始化");
2664
+ const state = this.store.payment.wallet.updateWalletAssetAmount(
2665
+ params.assetId,
2666
+ params.amount
2667
+ );
2668
+ await this.syncSelectedWalletAssets(state);
2669
+ return this.publishWalletAssetsState(state);
2670
+ }
2660
2671
  /** 扫码精确查券;仅可用资产会被自动选中。 */
2661
2672
  async scanWalletAsset(code) {
2662
2673
  if (!this.store.payment)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.3.60",
4
+ "version": "2.3.62",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",