@pisell/pisellos 2.2.19 → 2.2.20

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.
@@ -16,7 +16,7 @@ export declare const calculateSubtotal: (items: CartItem[]) => string;
16
16
  * @return {*}
17
17
  * @Author: xiangfeng.xue
18
18
  */
19
- export declare const calculateTaxFee: (shopInfo: any, items: CartItem[]) => Decimal | "0.00";
19
+ export declare const calculateTaxFee: (shopInfo: any, items: CartItem[]) => "0.00" | Decimal;
20
20
  /**
21
21
  * @title: 计算定金
22
22
  * @param items - 购物车商品数组
@@ -123,7 +123,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
123
123
  * 获取当前的客户搜索条件
124
124
  * @returns 当前搜索条件
125
125
  */
126
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
126
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
127
127
  /**
128
128
  * 获取客户列表状态(包含滚动加载相关状态)
129
129
  * @returns 客户状态
@@ -23,11 +23,14 @@ export declare class PaymentModule extends BaseModule implements Module, Payment
23
23
  private store;
24
24
  private dbManager;
25
25
  private logger;
26
+ private voucherUpdateLockByOrderUuid;
26
27
  protected otherParams: any;
27
28
  cash: CashPayment;
28
29
  eftpos: EftposPayment;
29
30
  wallet: WalletPassPayment;
30
31
  constructor(name?: string, version?: string);
32
+ private runVoucherUpdateLocked;
33
+ private normalizeVoucherPaymentItems;
31
34
  initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
32
35
  /**
33
36
  * 记录信息日志
@@ -68,11 +68,38 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
68
68
  this.defaultName = "pay";
69
69
  this.defaultVersion = "1.0.0";
70
70
  // LoggerManager 实例
71
+ this.voucherUpdateLockByOrderUuid = /* @__PURE__ */ new Map();
71
72
  this.otherParams = {};
72
73
  this.cash = new import_cash.CashPaymentImpl(this);
73
74
  this.eftpos = new import_eftpos.EftposPaymentImpl(this);
74
75
  this.wallet = new import_walletpass.WalletPassPaymentImpl(this);
75
76
  }
77
+ runVoucherUpdateLocked(orderUuid, task) {
78
+ const previous = this.voucherUpdateLockByOrderUuid.get(orderUuid) || Promise.resolve();
79
+ const next = previous.catch(() => void 0).then(task).finally(() => {
80
+ if (this.voucherUpdateLockByOrderUuid.get(orderUuid) === next) {
81
+ this.voucherUpdateLockByOrderUuid.delete(orderUuid);
82
+ }
83
+ });
84
+ this.voucherUpdateLockByOrderUuid.set(orderUuid, next);
85
+ return next;
86
+ }
87
+ normalizeVoucherPaymentItems(voucherPaymentItems) {
88
+ const normalized = /* @__PURE__ */ new Map();
89
+ for (const item of voucherPaymentItems || []) {
90
+ if (!(item == null ? void 0 : item.voucher_id)) {
91
+ throw new Error(`代金券支付项缺少 voucher_id: ${JSON.stringify(item)}`);
92
+ }
93
+ const orderPaymentType = item.order_payment_type || "normal";
94
+ const key = `${item.voucher_id}|${orderPaymentType}`;
95
+ normalized.set(key, { ...item, order_payment_type: orderPaymentType });
96
+ }
97
+ return {
98
+ items: Array.from(normalized.values()),
99
+ originalCount: (voucherPaymentItems == null ? void 0 : voucherPaymentItems.length) || 0,
100
+ normalizedCount: normalized.size
101
+ };
102
+ }
76
103
  async initialize(core, options) {
77
104
  this.core = core;
78
105
  this.store = options.store;
@@ -726,76 +753,102 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
726
753
  * 这是一个覆盖式更新,确保代金券支付项的一致性
727
754
  */
728
755
  async updateVoucherPaymentItemsAsync(orderUuid, voucherPaymentItems) {
729
- this.logInfo("Starting updateVoucherPaymentItemsAsync", {
730
- orderUuid,
731
- newVoucherCount: voucherPaymentItems.length,
732
- voucherItems: voucherPaymentItems.map((item) => ({
733
- code: item.code,
734
- amount: item.amount,
735
- voucher_id: item.voucher_id,
736
- order_payment_type: item.order_payment_type
737
- }))
738
- });
739
- try {
740
- const order = await this.getPaymentOrderByUuidAsync(orderUuid);
741
- if (!order) {
742
- throw new Error(`订单不存在: ${orderUuid}`);
743
- }
744
- const existingVoucherItems = order.payment.filter(
745
- (payment) => payment.voucher_id && payment.status !== "voided" && !payment.isSynced
746
- );
747
- console.log("[PaymentModule] 发现现有代金券支付项:", {
756
+ return this.runVoucherUpdateLocked(orderUuid, async () => {
757
+ const { items: normalizedVoucherItems, originalCount, normalizedCount } = this.normalizeVoucherPaymentItems(voucherPaymentItems);
758
+ this.logInfo("Starting updateVoucherPaymentItemsAsync", {
748
759
  orderUuid,
749
- existingVoucherCount: existingVoucherItems.length,
750
- existingItems: existingVoucherItems.map((item) => ({
751
- uuid: item.uuid,
760
+ originalVoucherCount: originalCount,
761
+ normalizedVoucherCount: normalizedCount,
762
+ voucherItems: normalizedVoucherItems.map((item) => ({
752
763
  code: item.code,
753
764
  amount: item.amount,
754
765
  voucher_id: item.voucher_id,
755
- isSynced: item.isSynced
766
+ order_payment_type: item.order_payment_type
756
767
  }))
757
768
  });
758
- for (const voucherItem of existingVoucherItems) {
759
- console.log(`[PaymentModule] 删除现有代金券支付项: ${voucherItem.uuid}`);
760
- await this.deletePaymentAsync(orderUuid, voucherItem.uuid);
769
+ if (originalCount !== normalizedCount) {
770
+ console.warn("[PaymentModule] voucherPaymentItems detected duplicates (deduped by voucher_id + order_payment_type)", {
771
+ orderUuid,
772
+ originalCount,
773
+ normalizedCount
774
+ });
761
775
  }
762
- console.log("[PaymentModule] 添加新的代金券支付项:", {
763
- orderUuid,
764
- newItemCount: voucherPaymentItems.length
765
- });
766
- for (const voucherItem of voucherPaymentItems) {
767
- if (!voucherItem.voucher_id) {
768
- throw new Error(`代金券支付项缺少 voucher_id: ${JSON.stringify(voucherItem)}`);
776
+ try {
777
+ const order = await this.getPaymentOrderByUuidAsync(orderUuid);
778
+ if (!order) {
779
+ throw new Error(`订单不存在: ${orderUuid}`);
780
+ }
781
+ const existingVoucherItems = order.payment.filter(
782
+ (payment) => payment.voucher_id && payment.status !== "voided" && !payment.isSynced
783
+ );
784
+ console.log("[PaymentModule] 发现现有代金券支付项:", {
785
+ orderUuid,
786
+ existingVoucherCount: existingVoucherItems.length,
787
+ existingItems: existingVoucherItems.map((item) => ({
788
+ uuid: item.uuid,
789
+ code: item.code,
790
+ amount: item.amount,
791
+ voucher_id: item.voucher_id,
792
+ isSynced: item.isSynced
793
+ }))
794
+ });
795
+ for (const voucherItem of existingVoucherItems) {
796
+ console.log(`[PaymentModule] 删除现有代金券支付项: ${voucherItem.uuid}`);
797
+ await this.deletePaymentAsync(orderUuid, voucherItem.uuid);
769
798
  }
770
- console.log(`[PaymentModule] 添加代金券支付项:`, {
771
- code: voucherItem.code,
772
- amount: voucherItem.amount,
773
- voucher_id: voucherItem.voucher_id,
774
- order_payment_type: voucherItem.order_payment_type
799
+ const orderAfterDelete = await this.getPaymentOrderByUuidAsync(orderUuid);
800
+ if (!orderAfterDelete) {
801
+ throw new Error(`订单不存在: ${orderUuid}`);
802
+ }
803
+ const existingActiveVoucherKeys = new Set(
804
+ orderAfterDelete.payment.filter((p) => p.voucher_id && p.status !== "voided").map((p) => `${p.voucher_id}|${p.order_payment_type || "normal"}`)
805
+ );
806
+ console.log("[PaymentModule] 添加新的代金券支付项:", {
807
+ orderUuid,
808
+ newItemCount: normalizedVoucherItems.length
809
+ });
810
+ for (const voucherItem of normalizedVoucherItems) {
811
+ const orderPaymentType = voucherItem.order_payment_type || "normal";
812
+ const key = `${voucherItem.voucher_id}|${orderPaymentType}`;
813
+ if (existingActiveVoucherKeys.has(key)) {
814
+ console.warn("[PaymentModule] Skip adding voucher payment item because it already exists (active)", {
815
+ orderUuid,
816
+ voucher_id: voucherItem.voucher_id,
817
+ order_payment_type: orderPaymentType
818
+ });
819
+ continue;
820
+ }
821
+ console.log(`[PaymentModule] 添加代金券支付项:`, {
822
+ code: voucherItem.code,
823
+ amount: voucherItem.amount,
824
+ voucher_id: voucherItem.voucher_id,
825
+ order_payment_type: orderPaymentType
826
+ });
827
+ await this.addPaymentItemAsync(orderUuid, voucherItem);
828
+ existingActiveVoucherKeys.add(key);
829
+ }
830
+ const updatedOrder = await this.getPaymentOrderByUuidAsync(orderUuid);
831
+ await this.core.effects.emit(`${this.name}:onPaymentAdded`, {
832
+ orderUuid,
833
+ order: updatedOrder,
834
+ payment: null
835
+ // 批量操作不提供单个支付项
836
+ });
837
+ this.logInfo("updateVoucherPaymentItemsAsync completed successfully", {
838
+ orderUuid,
839
+ removedVoucherCount: existingVoucherItems.length,
840
+ addedVoucherCount: normalizedVoucherItems.length,
841
+ finalExpectAmount: updatedOrder == null ? void 0 : updatedOrder.expect_amount
842
+ });
843
+ } catch (error) {
844
+ console.error("[PaymentModule] 批量更新代金券支付项失败:", error);
845
+ this.logError("updateVoucherPaymentItemsAsync failed", error, {
846
+ orderUuid,
847
+ voucherPaymentItems
775
848
  });
776
- await this.addPaymentItemAsync(orderUuid, voucherItem);
849
+ throw error;
777
850
  }
778
- const updatedOrder = await this.getPaymentOrderByUuidAsync(orderUuid);
779
- await this.core.effects.emit(`${this.name}:onPaymentAdded`, {
780
- orderUuid,
781
- order: updatedOrder,
782
- payment: null
783
- // 批量操作不提供单个支付项
784
- });
785
- this.logInfo("updateVoucherPaymentItemsAsync completed successfully", {
786
- orderUuid,
787
- removedVoucherCount: existingVoucherItems.length,
788
- addedVoucherCount: voucherPaymentItems.length,
789
- finalExpectAmount: updatedOrder == null ? void 0 : updatedOrder.expect_amount
790
- });
791
- } catch (error) {
792
- console.error("[PaymentModule] 批量更新代金券支付项失败:", error);
793
- this.logError("updateVoucherPaymentItemsAsync failed", error, {
794
- orderUuid,
795
- voucherPaymentItems
796
- });
797
- throw error;
798
- }
851
+ });
799
852
  }
800
853
  /**
801
854
  * 更新一个支付项
@@ -16,7 +16,7 @@ export declare const calculateSubtotal: (items: CartItem[]) => string;
16
16
  * @return {*}
17
17
  * @Author: xiangfeng.xue
18
18
  */
19
- export declare const calculateTaxFee: (shopInfo: any, items: CartItem[]) => Decimal | "0.00";
19
+ export declare const calculateTaxFee: (shopInfo: any, items: CartItem[]) => "0.00" | Decimal;
20
20
  /**
21
21
  * @title: 计算定金
22
22
  * @param items - 购物车商品数组
@@ -123,7 +123,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
123
123
  * 获取当前的客户搜索条件
124
124
  * @returns 当前搜索条件
125
125
  */
126
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
126
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
127
127
  /**
128
128
  * 获取客户列表状态(包含滚动加载相关状态)
129
129
  * @returns 客户状态
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.2.19",
4
+ "version": "2.2.20",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",