@pisell/pisellos 0.0.233 → 0.0.235

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 (37) hide show
  1. package/dist/modules/Order/index.d.ts +1 -1
  2. package/dist/modules/Order/index.js +1 -1
  3. package/dist/modules/Payment/index.d.ts +3 -3
  4. package/dist/modules/Payment/index.js +74 -10
  5. package/dist/modules/Payment/types.d.ts +24 -3
  6. package/dist/modules/Payment/types.js +9 -1
  7. package/dist/modules/Payment/utils.js +1 -1
  8. package/dist/modules/Payment/walletpass.d.ts +5 -2
  9. package/dist/modules/Payment/walletpass.js +63 -11
  10. package/dist/solution/BookingByStep/utils/timeslots.js +88 -38
  11. package/dist/solution/BookingTicket/index.d.ts +8 -0
  12. package/dist/solution/BookingTicket/index.js +27 -3
  13. package/dist/solution/BookingTicket/utils/scan/handleScan.d.ts +6 -0
  14. package/dist/solution/BookingTicket/utils/scan/handleScan.js +43 -28
  15. package/dist/solution/Checkout/index.d.ts +50 -7
  16. package/dist/solution/Checkout/index.js +890 -474
  17. package/dist/solution/Checkout/types.d.ts +69 -3
  18. package/dist/solution/Checkout/types.js +5 -0
  19. package/lib/modules/Order/index.d.ts +1 -1
  20. package/lib/modules/Order/index.js +1 -1
  21. package/lib/modules/Payment/index.d.ts +3 -3
  22. package/lib/modules/Payment/index.js +30 -5
  23. package/lib/modules/Payment/types.d.ts +24 -3
  24. package/lib/modules/Payment/types.js +1 -1
  25. package/lib/modules/Payment/utils.js +1 -1
  26. package/lib/modules/Payment/walletpass.d.ts +5 -2
  27. package/lib/modules/Payment/walletpass.js +30 -2
  28. package/lib/solution/BookingByStep/utils/timeslots.js +38 -3
  29. package/lib/solution/BookingTicket/index.d.ts +8 -0
  30. package/lib/solution/BookingTicket/index.js +23 -2
  31. package/lib/solution/BookingTicket/utils/scan/handleScan.d.ts +6 -0
  32. package/lib/solution/BookingTicket/utils/scan/handleScan.js +21 -14
  33. package/lib/solution/Checkout/index.d.ts +50 -7
  34. package/lib/solution/Checkout/index.js +267 -92
  35. package/lib/solution/Checkout/types.d.ts +69 -3
  36. package/lib/solution/Checkout/types.js +1 -0
  37. package/package.json +1 -1
@@ -389,7 +389,9 @@ export declare enum CheckoutHooks {
389
389
  /** 订单备注变更 */
390
390
  OnOrderNoteChanged = "checkout:onOrderNoteChanged",
391
391
  /** 商店折扣变更 */
392
- OnShopDiscountChanged = "checkout:onShopDiscountChanged"
392
+ OnShopDiscountChanged = "checkout:onShopDiscountChanged",
393
+ /** 订单取消 */
394
+ OnOrderCancelled = "checkout:onOrderCancelled"
393
395
  }
394
396
  /**
395
397
  * 结账状态数据
@@ -610,11 +612,12 @@ export interface CheckoutModuleAPI extends Module {
610
612
  orderUuid?: string;
611
613
  }>;
612
614
  /**
613
- * 检查订单是否需要手动同步
615
+ * 检查订单是否需要手动同步(异步版本)
614
616
  *
615
617
  * 返回订单是否为纯代金券支付且待付金额<=0但未同步的状态
618
+ * 从 Payment 模块获取最新的支付项数据
616
619
  */
617
- needsManualSync(): boolean;
620
+ needsManualSyncAsync(): Promise<boolean>;
618
621
  /**
619
622
  * 更新订单备注
620
623
  *
@@ -633,6 +636,25 @@ export interface CheckoutModuleAPI extends Module {
633
636
  * @returns 当前订单的ID,如果没有订单则返回null
634
637
  */
635
638
  getCurrentOrderId(): string | null;
639
+ /**
640
+ * 获取当前订单是否已同步到后端
641
+ *
642
+ * @returns 当前订单是否已同步状态,如果没有订单则返回false
643
+ */
644
+ isCurrentOrderSynced(): boolean;
645
+ /**
646
+ * 取消当前本地订单
647
+ *
648
+ * 只能取消未同步到后端的本地订单,如果订单已同步则不能取消
649
+ *
650
+ * @param cancelReason 取消原因(可选)
651
+ * @returns 取消结果
652
+ */
653
+ cancelCurrentOrderAsync(cancelReason?: string): Promise<{
654
+ success: boolean;
655
+ message?: string;
656
+ orderId?: string;
657
+ }>;
636
658
  /**
637
659
  * 更新订单商店折扣
638
660
  *
@@ -675,6 +697,42 @@ export interface CheckoutModuleAPI extends Module {
675
697
  message?: string;
676
698
  orderId?: string | number;
677
699
  }>;
700
+ /**
701
+ * 发送客户支付链接邮件
702
+ *
703
+ * 向指定邮箱发送订单支付提醒邮件
704
+ *
705
+ * @param params 发送参数
706
+ * @returns 发送结果
707
+ */
708
+ sendCustomerPayLinkAsync(params: SendCustomerPayLinkParams): Promise<{
709
+ success: boolean;
710
+ message?: string;
711
+ }>;
712
+ /**
713
+ * 金额舍入
714
+ *
715
+ * 根据系统配置的舍入设置对金额进行舍入处理
716
+ *
717
+ * @param amount 原始金额
718
+ * @returns 舍入结果详情,包含原始金额、舍入后金额和舍入差额
719
+ */
720
+ roundAmountAsync(amount: number): Promise<{
721
+ originalAmount: string;
722
+ roundedAmount: string;
723
+ roundingDifference: string;
724
+ }>;
725
+ }
726
+ /**
727
+ * 发送客户支付链接参数
728
+ */
729
+ export interface SendCustomerPayLinkParams {
730
+ /** 订单ID列表 */
731
+ order_ids: string[];
732
+ /** 通知动作,固定为订单支付提醒 */
733
+ notify_action?: string;
734
+ /** 邮箱地址列表 */
735
+ emails: string[];
678
736
  }
679
737
  /**
680
738
  * 结账事件数据类型
@@ -748,4 +806,12 @@ export interface CheckoutEventData {
748
806
  newDiscount: number;
749
807
  timestamp: number;
750
808
  };
809
+ /** 订单取消事件 */
810
+ orderCancelled: {
811
+ orderUuid?: string;
812
+ orderId?: string;
813
+ cancelReason?: string;
814
+ wasSynced: boolean;
815
+ timestamp: number;
816
+ };
751
817
  }
@@ -117,6 +117,7 @@ export var CheckoutHooks = /*#__PURE__*/function (CheckoutHooks) {
117
117
  CheckoutHooks["OnOrderSynced"] = "checkout:onOrderSynced";
118
118
  CheckoutHooks["OnOrderNoteChanged"] = "checkout:onOrderNoteChanged";
119
119
  CheckoutHooks["OnShopDiscountChanged"] = "checkout:onShopDiscountChanged";
120
+ CheckoutHooks["OnOrderCancelled"] = "checkout:onOrderCancelled";
120
121
  return CheckoutHooks;
121
122
  }({});
122
123
 
@@ -132,6 +133,10 @@ export var CheckoutHooks = /*#__PURE__*/function (CheckoutHooks) {
132
133
  * 结账解决方案 API 接口
133
134
  */
134
135
 
136
+ /**
137
+ * 发送客户支付链接参数
138
+ */
139
+
135
140
  /**
136
141
  * 结账事件数据类型
137
142
  */
@@ -11,7 +11,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
11
11
  initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
12
12
  createOrder(params: CommitOrderParams['query']): {
13
13
  type: "virtual" | "appointment_booking";
14
- platform: "pc" | "h5";
14
+ platform: string;
15
15
  sales_channel: string;
16
16
  order_sales_channel: string;
17
17
  bookings: any[];
@@ -41,7 +41,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
41
41
  const order = {
42
42
  type: (params == null ? void 0 : params.type) || "appointment_booking",
43
43
  // 要从外面拿,virtual
44
- platform: (params == null ? void 0 : params.platform) || "pc",
44
+ platform: (params == null ? void 0 : params.platform) === "pc" ? "PC" : "H5",
45
45
  sales_channel: "my_pisel",
46
46
  order_sales_channel: "online_store",
47
47
  bookings: [],
@@ -1,7 +1,7 @@
1
1
  import { Module, PisellCore, ModuleOptions } from '../../types';
2
2
  import { RequestPlugin } from '../../plugins';
3
3
  import { BaseModule } from '../BaseModule';
4
- import { PaymentModuleAPI, PaymentMethod, PaymentOrder, PaymentItem, PaymentItemInput, PaymentUpdateFields, PushOrderParams, CashPayment, EftposPayment, WalletPassPayment, RoundingRule, RoundingInterval } from './types';
4
+ import { PaymentModuleAPI, PaymentMethod, PaymentOrder, PaymentItem, PaymentItemInput, PaymentUpdateFields, PushOrderParams, CashPayment, EftposPayment, WalletPassPayment, RoundingRule, RoundingInterval, RoundingResult } from './types';
5
5
  export * from './types';
6
6
  export { generateRequestUniqueId };
7
7
  /**
@@ -176,9 +176,9 @@ export declare class PaymentModule extends BaseModule implements Module, Payment
176
176
  * @param originalAmount 原始金额
177
177
  * @param interval 舍入间隔 (0.05, 0.1, 0.5, 1)
178
178
  * @param rule 舍入规则 (standard, standard_down, always_up, always_down)
179
- * @returns 舍入后的金额(保留两位小数的字符串)
179
+ * @returns 舍入结果详情(包含原始金额、舍入后金额和舍入差额)
180
180
  */
181
- roundAmountAsync(originalAmount: number | string, interval: RoundingInterval | number, rule: RoundingRule | string): Promise<string>;
181
+ roundAmountAsync(originalAmount: number | string, interval: RoundingInterval | number, rule: RoundingRule | string): Promise<RoundingResult>;
182
182
  /**
183
183
  * 标准舍入处理(处理中点情况)
184
184
  *
@@ -257,7 +257,25 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
257
257
  if (!oldMethod) {
258
258
  return true;
259
259
  }
260
- if (oldMethod.code !== newMethod.code || oldMethod.name !== newMethod.name || oldMethod.type !== newMethod.type || oldMethod.enabled !== newMethod.enabled) {
260
+ if (oldMethod.code !== newMethod.code || oldMethod.name !== newMethod.name || oldMethod.type !== newMethod.type || oldMethod.description !== newMethod.description || oldMethod.status !== newMethod.status || oldMethod.disable !== newMethod.disable || oldMethod.is_surcharge !== newMethod.is_surcharge || oldMethod.fixed !== newMethod.fixed || oldMethod.percentage !== newMethod.percentage || oldMethod.enabled !== newMethod.enabled || JSON.stringify(oldMethod.channel_application || []) !== JSON.stringify(newMethod.channel_application || []) || JSON.stringify(oldMethod.companies || []) !== JSON.stringify(newMethod.companies || []) || JSON.stringify(oldMethod.metadata || {}) !== JSON.stringify(newMethod.metadata || {})) {
261
+ console.log(`[PaymentModule] 支付方式 ${newMethod.id} (${newMethod.code}) 发生变化:`, {
262
+ id: newMethod.id,
263
+ changes: {
264
+ code: oldMethod.code !== newMethod.code ? { old: oldMethod.code, new: newMethod.code } : void 0,
265
+ name: oldMethod.name !== newMethod.name ? { old: oldMethod.name, new: newMethod.name } : void 0,
266
+ type: oldMethod.type !== newMethod.type ? { old: oldMethod.type, new: newMethod.type } : void 0,
267
+ description: oldMethod.description !== newMethod.description ? { old: oldMethod.description, new: newMethod.description } : void 0,
268
+ status: oldMethod.status !== newMethod.status ? { old: oldMethod.status, new: newMethod.status } : void 0,
269
+ disable: oldMethod.disable !== newMethod.disable ? { old: oldMethod.disable, new: newMethod.disable } : void 0,
270
+ is_surcharge: oldMethod.is_surcharge !== newMethod.is_surcharge ? { old: oldMethod.is_surcharge, new: newMethod.is_surcharge } : void 0,
271
+ fixed: oldMethod.fixed !== newMethod.fixed ? { old: oldMethod.fixed, new: newMethod.fixed } : void 0,
272
+ percentage: oldMethod.percentage !== newMethod.percentage ? { old: oldMethod.percentage, new: newMethod.percentage } : void 0,
273
+ enabled: oldMethod.enabled !== newMethod.enabled ? { old: oldMethod.enabled, new: newMethod.enabled } : void 0,
274
+ channel_application: JSON.stringify(oldMethod.channel_application || []) !== JSON.stringify(newMethod.channel_application || []) ? { old: oldMethod.channel_application, new: newMethod.channel_application } : void 0,
275
+ companies: JSON.stringify(oldMethod.companies || []) !== JSON.stringify(newMethod.companies || []) ? { old: oldMethod.companies, new: newMethod.companies } : void 0,
276
+ metadata: JSON.stringify(oldMethod.metadata || {}) !== JSON.stringify(newMethod.metadata || {}) ? { old: oldMethod.metadata, new: newMethod.metadata } : void 0
277
+ }
278
+ });
261
279
  return true;
262
280
  }
263
281
  }
@@ -948,7 +966,7 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
948
966
  * @param originalAmount 原始金额
949
967
  * @param interval 舍入间隔 (0.05, 0.1, 0.5, 1)
950
968
  * @param rule 舍入规则 (standard, standard_down, always_up, always_down)
951
- * @returns 舍入后的金额(保留两位小数的字符串)
969
+ * @returns 舍入结果详情(包含原始金额、舍入后金额和舍入差额)
952
970
  */
953
971
  async roundAmountAsync(originalAmount, interval, rule) {
954
972
  try {
@@ -986,9 +1004,16 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
986
1004
  throw new Error(`不支持的舍入规则: ${rule}`);
987
1005
  }
988
1006
  const finalAmount = roundedValue.mul(roundingInterval);
989
- const result = finalAmount.toFixed(2);
990
- console.log(`[PaymentModule] 舍入结果 - 舍入值: ${roundedValue.toString()}, 最终金额: ${result}`);
991
- return result;
1007
+ const roundedAmountStr = finalAmount.toFixed(2);
1008
+ const originalAmountStr = amount.toFixed(2);
1009
+ const roundingDifference = finalAmount.sub(amount);
1010
+ const roundingDifferenceStr = roundingDifference.toFixed(2);
1011
+ console.log(`[PaymentModule] 舍入结果 - 原始金额: ${originalAmountStr}, 舍入后金额: ${roundedAmountStr}, 舍入差额: ${roundingDifferenceStr}`);
1012
+ return {
1013
+ originalAmount: originalAmountStr,
1014
+ roundedAmount: roundedAmountStr,
1015
+ roundingDifference: roundingDifferenceStr
1016
+ };
992
1017
  } catch (error) {
993
1018
  console.error("[PaymentModule] 金额舍入失败:", error);
994
1019
  throw new Error(`金额舍入失败: ${error instanceof Error ? error.message : String(error)}`);
@@ -36,7 +36,7 @@ export declare enum TaskRunStatus {
36
36
  */
37
37
  export declare enum RoundingRule {
38
38
  /** 标准舍入(中点向上) */
39
- Standard = "standard",
39
+ Standard = "standard_rounding",
40
40
  /** 标准舍入(中点向下) */
41
41
  StandardDown = "standard_down",
42
42
  /** 总是向上舍入 */
@@ -44,6 +44,17 @@ export declare enum RoundingRule {
44
44
  /** 总是向下舍入 */
45
45
  AlwaysDown = "always_down"
46
46
  }
47
+ /**
48
+ * 舍入结果
49
+ */
50
+ export interface RoundingResult {
51
+ /** 原始金额 */
52
+ originalAmount: string;
53
+ /** 舍入后的金额 */
54
+ roundedAmount: string;
55
+ /** 舍入差额(舍入后金额 - 原始金额) */
56
+ roundingDifference: string;
57
+ }
47
58
  /**
48
59
  * 舍入间隔枚举
49
60
  */
@@ -306,7 +317,7 @@ export interface WalletPassPayment {
306
317
  /** 查询用户识别码列表(异步获取并缓存) */
307
318
  getUserIdentificationCodeListAsync: (params: UserIdentificationCodeParams) => Promise<UserIdentificationCodeItem[]>;
308
319
  /** 搜索识别码信息 */
309
- searchIdentificationCodeAsync: (params: SearchIdentificationCodeParams) => Promise<SearchIdentificationCodeItem[]>;
320
+ searchIdentificationCodeAsync: (params: SearchIdentificationCodeParams) => Promise<SearchIdentificationCodeResult>;
310
321
  /** 获取缓存的搜索结果列表 */
311
322
  getSearchResults: () => SearchIdentificationCodeItem[];
312
323
  /** 根据识别码查找搜索结果 */
@@ -371,7 +382,7 @@ export interface PaymentModuleAPI {
371
382
  * @param rule 舍入规则 (standard, standard_down, always_up, always_down)
372
383
  * @returns 舍入后的金额
373
384
  */
374
- roundAmountAsync: (originalAmount: number | string, interval: RoundingInterval | number, rule: RoundingRule | string) => Promise<string>;
385
+ roundAmountAsync: (originalAmount: number | string, interval: RoundingInterval | number, rule: RoundingRule | string) => Promise<RoundingResult>;
375
386
  /** 提交支付 */
376
387
  submitPayAsync: (orderUuid?: string) => Promise<{
377
388
  status: 'success' | 'failed';
@@ -636,6 +647,16 @@ export interface SearchIdentificationCodeResponse {
636
647
  /** 响应数据 */
637
648
  data?: SearchIdentificationCodeItem[];
638
649
  }
650
+ /**
651
+ * 搜索识别码结果类型
652
+ */
653
+ export type SearchIdentificationCodeResult = {
654
+ type: 'walletCode';
655
+ data: SearchIdentificationCodeItem[];
656
+ } | {
657
+ type: 'normalCode';
658
+ data: SearchIdentificationCodeItem[];
659
+ };
639
660
  /**
640
661
  * 搜索识别码项目
641
662
  */
@@ -49,7 +49,7 @@ var TaskRunStatus = /* @__PURE__ */ ((TaskRunStatus2) => {
49
49
  return TaskRunStatus2;
50
50
  })(TaskRunStatus || {});
51
51
  var RoundingRule = /* @__PURE__ */ ((RoundingRule2) => {
52
- RoundingRule2["Standard"] = "standard";
52
+ RoundingRule2["Standard"] = "standard_rounding";
53
53
  RoundingRule2["StandardDown"] = "standard_down";
54
54
  RoundingRule2["AlwaysUp"] = "always_up";
55
55
  RoundingRule2["AlwaysDown"] = "always_down";
@@ -31,7 +31,7 @@ var formatWalletPassList2PreparePayments = (list) => {
31
31
  return (list || []).map((item) => {
32
32
  return {
33
33
  voucher_id: item.id || 0,
34
- amount: Number(getAvailableMaxAmount(item)) || 0,
34
+ amount: Number(item.edit_current_amount || getAvailableMaxAmount(item)) || 0,
35
35
  tag: item.tag || ""
36
36
  };
37
37
  });
@@ -1,4 +1,4 @@
1
- import { WalletPassPayment, WalletDeductionRecommendParams, WalletRecommendItem, UserIdentificationCodeParams, UserIdentificationCodeItem, SearchIdentificationCodeParams, SearchIdentificationCodeItem, WalletInitBusinessData } from './types';
1
+ import { WalletPassPayment, WalletDeductionRecommendParams, WalletRecommendItem, UserIdentificationCodeParams, UserIdentificationCodeItem, SearchIdentificationCodeParams, SearchIdentificationCodeItem, SearchIdentificationCodeResult, WalletInitBusinessData } from './types';
2
2
  import type { PaymentModule } from './index';
3
3
  /**
4
4
  * 钱包支付实现
@@ -57,8 +57,11 @@ export declare class WalletPassPaymentImpl implements WalletPassPayment {
57
57
  * 搜索识别码信息
58
58
  * 通过识别码搜索相关的钱包通行证信息
59
59
  * 基于 WalletDeductionRecommendParams 参数结构
60
+ * 特殊逻辑:当识别码长度为9位且前3位为"000"时,调用 /wallet/detail/search 接口
60
61
  */
61
- searchIdentificationCodeAsync(params: SearchIdentificationCodeParams): Promise<SearchIdentificationCodeItem[]>;
62
+ searchIdentificationCodeAsync(params: SearchIdentificationCodeParams, config?: {
63
+ noCache?: boolean;
64
+ }): Promise<SearchIdentificationCodeResult>;
62
65
  processWalletPayment(amount: number, orderUuid: string, voucherId?: string): Promise<void>;
63
66
  getWalletBalance(voucherId: string): Promise<number>;
64
67
  /**
@@ -175,9 +175,28 @@ var WalletPassPaymentImpl = class {
175
175
  * 搜索识别码信息
176
176
  * 通过识别码搜索相关的钱包通行证信息
177
177
  * 基于 WalletDeductionRecommendParams 参数结构
178
+ * 特殊逻辑:当识别码长度为9位且前3位为"000"时,调用 /wallet/detail/search 接口
178
179
  */
179
- async searchIdentificationCodeAsync(params) {
180
+ async searchIdentificationCodeAsync(params, config = {}) {
180
181
  try {
182
+ const { code } = params;
183
+ const isWalletCode = code.startsWith("WL");
184
+ if (isWalletCode) {
185
+ const walletDetailParams = {
186
+ code,
187
+ with_customer: 1,
188
+ with: ["latestWalletDetail.wallet"]
189
+ };
190
+ const response2 = await this.paymentModule.request.post(
191
+ "/wallet/detail/search",
192
+ walletDetailParams
193
+ );
194
+ const searchResults2 = (response2 == null ? void 0 : response2.data) || [];
195
+ return {
196
+ type: "walletCode",
197
+ data: searchResults2
198
+ };
199
+ }
181
200
  const baseWalletParams = this.walletParams;
182
201
  const searchParams = {
183
202
  // 基础钱包参数
@@ -198,6 +217,12 @@ var WalletPassPaymentImpl = class {
198
217
  searchParams
199
218
  );
200
219
  const searchResults = (response == null ? void 0 : response.data) || [];
220
+ if (config.noCache) {
221
+ return {
222
+ type: "normalCode",
223
+ data: searchResults
224
+ };
225
+ }
201
226
  if (searchResults.length > 0) {
202
227
  const existingCodes = new Set(
203
228
  this.searchResults.map((item) => item.code)
@@ -213,7 +238,10 @@ var WalletPassPaymentImpl = class {
213
238
  cachedSearchResults: [...this.searchResults],
214
239
  searchParams: params
215
240
  });
216
- return searchResults;
241
+ return {
242
+ type: "normalCode",
243
+ data: searchResults
244
+ };
217
245
  } catch (error) {
218
246
  console.error("[WalletPass] 搜索识别码信息失败:", error);
219
247
  throw error;
@@ -79,7 +79,7 @@ function findFastestAvailableResource({
79
79
  currentCapacity = 1,
80
80
  countMap = {}
81
81
  }) {
82
- var _a, _b;
82
+ var _a, _b, _c;
83
83
  const currentTime = (0, import_dayjs.default)();
84
84
  let fastestTime = null;
85
85
  let fastestResources = [];
@@ -168,8 +168,43 @@ function findFastestAvailableResource({
168
168
  console.log(`[TimeslotUtils] 返回唯一最快资源: ${fastestResources[0].main_field}`);
169
169
  return fastestResources[0];
170
170
  }
171
- const selectedResource = fastestResources[0];
172
- console.log(`[TimeslotUtils] 返回多个资源中的第一个: ${selectedResource.main_field}`);
171
+ let selectedResource = fastestResources[0];
172
+ let maxIdleTime = 0;
173
+ console.log(`[TimeslotUtils] 比较 ${fastestResources.length} 个资源的空闲时间:`);
174
+ for (const resource of fastestResources) {
175
+ const workingTime = resource.times.find((time) => {
176
+ const isToday = (0, import_dayjs.default)(time.start_at).isSame(fastestTime, "day");
177
+ const isStillWorking = (0, import_dayjs.default)(time.end_at).isAfter(fastestTime);
178
+ return isToday && isStillWorking;
179
+ });
180
+ if (!workingTime)
181
+ continue;
182
+ const workEndTime = (0, import_dayjs.default)(workingTime.end_at);
183
+ let totalIdleTime = workEndTime.diff(fastestTime, "minute");
184
+ const relevantEvents = ((_c = workingTime.event_list) == null ? void 0 : _c.filter((event) => {
185
+ const eventStart = (0, import_dayjs.default)(event.start_at);
186
+ const eventEnd = (0, import_dayjs.default)(event.end_at);
187
+ return eventEnd.isAfter(fastestTime) && eventStart.isAfter(fastestTime);
188
+ })) || [];
189
+ for (const event of relevantEvents) {
190
+ const eventStart = (0, import_dayjs.default)(event.start_at);
191
+ const eventEnd = (0, import_dayjs.default)(event.end_at);
192
+ const eventDuration = eventEnd.diff(eventStart, "minute");
193
+ totalIdleTime -= eventDuration;
194
+ }
195
+ console.log(`[TimeslotUtils] 资源 ${resource.id}(${resource.main_field}):`, {
196
+ 工作结束时间: workEndTime.format("HH:mm"),
197
+ 总工作时长: workEndTime.diff(fastestTime, "minute") + "分钟",
198
+ 预约占用时长: workEndTime.diff(fastestTime, "minute") - totalIdleTime + "分钟",
199
+ 实际空闲时长: totalIdleTime + "分钟"
200
+ });
201
+ if (totalIdleTime > maxIdleTime) {
202
+ maxIdleTime = totalIdleTime;
203
+ selectedResource = resource;
204
+ console.log(`[TimeslotUtils] 更新最佳选择: ${resource.main_field} (空闲${totalIdleTime}分钟)`);
205
+ }
206
+ }
207
+ console.log(`[TimeslotUtils] 最终选择资源: ${selectedResource.main_field} (最长空闲${maxIdleTime}分钟)`);
173
208
  return selectedResource;
174
209
  }
175
210
  function filterConditionTimeSlots(times, startTime, endTime) {
@@ -131,6 +131,14 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
131
131
  scanCustomerListener(callback: (data: IScanResult) => void): {
132
132
  remove: () => void;
133
133
  };
134
+ /**
135
+ * @title 通用扫描监听
136
+ * @description 直接将扫描结果返回给调用方
137
+ * @param callback 回调
138
+ */
139
+ scanUniversalListener(callback: (data: IScanResult) => void, key: string): {
140
+ remove: () => void;
141
+ };
134
142
  /**
135
143
  * 调用摄像头
136
144
  * @param data 用户自定义数据
@@ -302,7 +302,7 @@ var BookingTicketImpl = class extends import_BaseModule.BaseModule {
302
302
  try {
303
303
  callback(d);
304
304
  } catch (error) {
305
- console.error("scanGlobalListener回掉函数异常", error);
305
+ console.error("scanGlobalListener传入的回调函数异常", error);
306
306
  }
307
307
  };
308
308
  const listener = { key: "global", callback: safeCallback };
@@ -319,13 +319,34 @@ var BookingTicketImpl = class extends import_BaseModule.BaseModule {
319
319
  try {
320
320
  callback(d);
321
321
  } catch (error) {
322
- console.error("scanCustomerListener回掉函数异常", error);
322
+ console.error("scanCustomerListener传入的回调函数异常", error);
323
323
  }
324
324
  };
325
325
  const listener = { key: "customer", callback: safeCallback };
326
326
  const removeListener = this.scan.addListener(listener, scanCallback);
327
327
  return removeListener;
328
328
  }
329
+ /**
330
+ * @title 通用扫描监听
331
+ * @description 直接将扫描结果返回给调用方
332
+ * @param callback 回调
333
+ */
334
+ scanUniversalListener(callback, key) {
335
+ const scanCallback = (0, import_handleScan.handleUniversalScan)();
336
+ const safeCallback = (d) => {
337
+ try {
338
+ callback(d);
339
+ } catch (error) {
340
+ console.error(
341
+ `scanUniversalListener传入的回调函数异常, key: ${key}`,
342
+ error
343
+ );
344
+ }
345
+ };
346
+ const listener = { key, callback: safeCallback };
347
+ const removeListener = this.scan.addListener(listener, scanCallback);
348
+ return removeListener;
349
+ }
329
350
  /**
330
351
  * 调用摄像头
331
352
  * @param data 用户自定义数据
@@ -14,3 +14,9 @@ export declare const handleGlobalScan: (request: RequestPlugin, localSearch: (v:
14
14
  * @returns 处理结果
15
15
  */
16
16
  export declare const handleCustomerScan: () => () => Promise<{}>;
17
+ /**
18
+ * 处理钱包扫码
19
+ * @param request 请求插件
20
+ * @returns 处理结果
21
+ */
22
+ export declare const handleUniversalScan: () => () => Promise<{}>;
@@ -30,7 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  var handleScan_exports = {};
31
31
  __export(handleScan_exports, {
32
32
  handleCustomerScan: () => handleCustomerScan,
33
- handleGlobalScan: () => handleGlobalScan
33
+ handleGlobalScan: () => handleGlobalScan,
34
+ handleUniversalScan: () => handleUniversalScan
34
35
  });
35
36
  module.exports = __toCommonJS(handleScan_exports);
36
37
  var import_cloudSearch = require("./cloudSearch");
@@ -61,19 +62,21 @@ var promiseAny = async (promises) => {
61
62
  var handleScanFn = (getRequestList, localSearch) => {
62
63
  return async (scanResult) => {
63
64
  const { value } = scanResult || {};
64
- try {
65
- const localResult = localSearch == null ? void 0 : localSearch(value);
66
- if ((localResult == null ? void 0 : localResult.length) > 0) {
67
- console.log("本地搜索到数据>>>>>>>", localResult);
68
- return {
69
- searchType: "local_product",
70
- response: { data: { list: localResult } }
71
- };
72
- } else {
73
- console.log("本地搜索无数据>>>>>>>");
65
+ if (localSearch) {
66
+ try {
67
+ const localResult = localSearch == null ? void 0 : localSearch(value);
68
+ if ((localResult == null ? void 0 : localResult.length) > 0) {
69
+ console.log("本地搜索到数据>>>>>>>", localResult);
70
+ return {
71
+ searchType: "local_product",
72
+ response: { data: { list: localResult } }
73
+ };
74
+ } else {
75
+ console.log("本地搜索无数据>>>>>>>");
76
+ }
77
+ } catch (error) {
78
+ console.error("本地搜索到数据失败>>>>>>>", error);
74
79
  }
75
- } catch (error) {
76
- console.error("本地搜索到数据失败>>>>>>>", error);
77
80
  }
78
81
  try {
79
82
  if (import_scanCache.default.has(value)) {
@@ -118,8 +121,12 @@ var handleGlobalScan = (request, localSearch) => {
118
121
  var handleCustomerScan = () => {
119
122
  return () => Promise.resolve({});
120
123
  };
124
+ var handleUniversalScan = () => {
125
+ return () => Promise.resolve({});
126
+ };
121
127
  // Annotate the CommonJS export names for ESM import in node:
122
128
  0 && (module.exports = {
123
129
  handleCustomerScan,
124
- handleGlobalScan
130
+ handleGlobalScan,
131
+ handleUniversalScan
125
132
  });
@@ -2,7 +2,7 @@ import { Module, PisellCore, ModuleOptions } from '../../types';
2
2
  import { BaseModule } from '../../modules/BaseModule';
3
3
  import { OrderModule } from '../../modules/Order';
4
4
  import { PaymentModule } from '../../modules/Payment';
5
- import { CheckoutModuleAPI, CheckoutStep, CheckoutInitParams, CreateLocalOrderParams, PlaceOrderParams, CreateOrderParams, ProcessPaymentParams, CheckoutStatusInfo, CheckoutSummary, CurrentOrderInfo, CartSummaryItem, ExtractedAmountInfo } from './types';
5
+ import { CheckoutModuleAPI, CheckoutStep, CheckoutInitParams, CreateLocalOrderParams, PlaceOrderParams, CreateOrderParams, ProcessPaymentParams, CheckoutStatusInfo, CheckoutSummary, CurrentOrderInfo, CartSummaryItem, ExtractedAmountInfo, SendCustomerPayLinkParams } from './types';
6
6
  import { PaymentOrder, PaymentMethod, PaymentItem, PaymentItemInput } from '../../modules/Payment/types';
7
7
  export * from './types';
8
8
  /**
@@ -251,11 +251,12 @@ export declare class CheckoutImpl extends BaseModule implements Module, Checkout
251
251
  customer_name?: string;
252
252
  } | null;
253
253
  /**
254
- * 检查订单是否需要手动同步
254
+ * 检查订单是否需要手动同步(异步版本)
255
255
  *
256
256
  * 返回订单是否为纯代金券支付且待付金额<=0但未同步的状态
257
+ * 从 Payment 模块获取最新的支付项数据
257
258
  */
258
- needsManualSync(): boolean;
259
+ needsManualSyncAsync(): Promise<boolean>;
259
260
  /**
260
261
  * 手动同步订单到后端
261
262
  *
@@ -279,6 +280,25 @@ export declare class CheckoutImpl extends BaseModule implements Module, Checkout
279
280
  * @returns 当前订单的ID,如果没有订单则返回null
280
281
  */
281
282
  getCurrentOrderId(): string | null;
283
+ /**
284
+ * 获取当前订单是否已同步到后端
285
+ *
286
+ * @returns 当前订单是否已同步状态,如果没有订单则返回false
287
+ */
288
+ isCurrentOrderSynced(): boolean;
289
+ /**
290
+ * 取消当前本地订单
291
+ *
292
+ * 只能取消未同步到后端的本地订单,如果订单已同步则不能取消
293
+ *
294
+ * @param cancelReason 取消原因(可选)
295
+ * @returns 取消结果
296
+ */
297
+ cancelCurrentOrderAsync(cancelReason?: string): Promise<{
298
+ success: boolean;
299
+ message?: string;
300
+ orderId?: string;
301
+ }>;
282
302
  /**
283
303
  * 保存订单并稍后支付
284
304
  *
@@ -363,13 +383,13 @@ export declare class CheckoutImpl extends BaseModule implements Module, Checkout
363
383
  */
364
384
  private calculateTotalAmount;
365
385
  /**
366
- * 计算已支付金额
386
+ * 计算已支付金额(从 Payment 模块获取最新数据)
367
387
  */
368
- private calculatePaidAmount;
388
+ private calculatePaidAmountAsync;
369
389
  /**
370
- * 计算剩余未支付金额
390
+ * 计算剩余未支付金额(从 Payment 模块获取最新数据)
371
391
  */
372
- private calculateRemainingAmount;
392
+ private calculateRemainingAmountAsync;
373
393
  /**
374
394
  * 更新 stateAmount 为当前剩余未支付金额
375
395
  */
@@ -432,5 +452,28 @@ export declare class CheckoutImpl extends BaseModule implements Module, Checkout
432
452
  message?: string;
433
453
  orderId?: string | number;
434
454
  }>;
455
+ /**
456
+ * 发送客户支付链接邮件
457
+ *
458
+ * 向指定邮箱发送订单支付提醒邮件
459
+ *
460
+ * @param params 发送参数
461
+ * @returns 发送结果
462
+ */
463
+ sendCustomerPayLinkAsync(params: SendCustomerPayLinkParams): Promise<{
464
+ success: boolean;
465
+ message?: string;
466
+ }>;
467
+ /**
468
+ * 金额舍入
469
+ *
470
+ * @param amount 原始金额
471
+ * @returns 舍入结果详情,包含原始金额、舍入后金额和舍入差额
472
+ */
473
+ roundAmountAsync(amount: number): Promise<{
474
+ originalAmount: string;
475
+ roundedAmount: string;
476
+ roundingDifference: string;
477
+ }>;
435
478
  destroy(): Promise<void>;
436
479
  }