@pisell/pisellos 2.3.137 → 2.3.139

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 (40) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  2. package/dist/modules/Order/utils.js +1 -1
  3. package/dist/modules/ResourcePlanner/planner.js +10 -8
  4. package/dist/server/test.json +1 -1
  5. package/dist/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
  6. package/dist/shared/receipt/customerInvoiceLanguages.js +60 -0
  7. package/dist/shared/receipt/loadCustomerInvoiceLayout.d.ts +5 -0
  8. package/dist/shared/receipt/loadCustomerInvoiceLayout.js +46 -4
  9. package/dist/shared/receipt/small-ticket.d.ts +9 -0
  10. package/dist/shared/receipt/small-ticket.js +246 -186
  11. package/dist/solution/OrderInvoicePreview/index.d.ts +10 -0
  12. package/dist/solution/OrderInvoicePreview/index.js +84 -14
  13. package/dist/solution/RegisterAndLogin/config.js +33 -11
  14. package/dist/solution/RegisterAndLogin/index.d.ts +2 -0
  15. package/dist/solution/RegisterAndLogin/index.js +1 -1
  16. package/dist/solution/RegisterAndLogin/utils.d.ts +12 -4
  17. package/dist/solution/RegisterAndLogin/utils.js +36 -16
  18. package/dist/solution/Sales/index.d.ts +2 -0
  19. package/dist/solution/Sales/index.js +15 -1
  20. package/dist/solution/UnifiedBookingSales/index.js +3 -4
  21. package/lib/modules/Order/utils.js +1 -1
  22. package/lib/modules/ResourcePlanner/planner.js +10 -8
  23. package/lib/server/test.json +1 -1
  24. package/lib/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
  25. package/lib/shared/receipt/customerInvoiceLanguages.js +58 -0
  26. package/lib/shared/receipt/loadCustomerInvoiceLayout.d.ts +5 -0
  27. package/lib/shared/receipt/loadCustomerInvoiceLayout.js +42 -4
  28. package/lib/shared/receipt/small-ticket.d.ts +9 -0
  29. package/lib/shared/receipt/small-ticket.js +122 -9
  30. package/lib/solution/OrderInvoicePreview/index.d.ts +10 -0
  31. package/lib/solution/OrderInvoicePreview/index.js +60 -7
  32. package/lib/solution/RegisterAndLogin/config.js +32 -11
  33. package/lib/solution/RegisterAndLogin/index.d.ts +2 -0
  34. package/lib/solution/RegisterAndLogin/index.js +9 -1
  35. package/lib/solution/RegisterAndLogin/utils.d.ts +12 -4
  36. package/lib/solution/RegisterAndLogin/utils.js +24 -17
  37. package/lib/solution/Sales/index.d.ts +2 -0
  38. package/lib/solution/Sales/index.js +10 -1
  39. package/lib/solution/UnifiedBookingSales/index.js +3 -4
  40. package/package.json +1 -1
@@ -588,6 +588,16 @@ const defaultConfig = {
588
588
  /**
589
589
  * webpos 渠道配置
590
590
  */
591
+ const webposPasswordResetOptions = {
592
+ prefix: false,
593
+ isDefaultSaasDomain: true,
594
+ cache: false,
595
+ noToast: true,
596
+ headers: {
597
+ Accept: 'application/json',
598
+ 'Content-Type': 'application/json'
599
+ }
600
+ };
591
601
  const webposConfig = {
592
602
  sendEmailVerificationCode: {
593
603
  url: '/auth/email/register-code',
@@ -710,13 +720,20 @@ const webposConfig = {
710
720
  })
711
721
  },
712
722
  checkEmailCode: {
713
- url: '/auth/email/check-email-code',
714
- method: 'GET',
723
+ url: '/tenant/account/reset-password/email-code/verify',
724
+ method: 'POST',
715
725
  transformParams: params => ({
716
726
  email: params.email,
717
- code: params.code,
718
- action: params.action
719
- })
727
+ code: params.code
728
+ }),
729
+ // SaaS 成功时 data 为 null,统一为既有验证码校验返回结构。
730
+ transformResponse: response => response?.status === true ? {
731
+ ...response,
732
+ data: {
733
+ valid: true
734
+ }
735
+ } : response,
736
+ options: webposPasswordResetOptions
720
737
  },
721
738
  checkMobileCode: {
722
739
  url: '/auth/mobile/check-mobile-code',
@@ -738,11 +755,12 @@ const webposConfig = {
738
755
  })
739
756
  },
740
757
  sendPasswordResetEmail: {
741
- url: '/auth/email/reset-password-code',
742
- method: 'GET',
758
+ url: '/tenant/account/reset-password/email-code/send',
759
+ method: 'POST',
743
760
  transformParams: params => ({
744
761
  email: params.email
745
- })
762
+ }),
763
+ options: webposPasswordResetOptions
746
764
  },
747
765
  sendPasswordResetSms: {
748
766
  url: '/auth/mobile/sms-forget',
@@ -775,13 +793,16 @@ const webposConfig = {
775
793
  })
776
794
  },
777
795
  resetPasswordByEmail: {
778
- url: '/auth/email/reset-password',
796
+ url: '/tenant/account/reset-password/email-code',
779
797
  method: 'POST',
780
798
  transformParams: params => ({
781
799
  email: params.email,
782
800
  password: params.password,
783
- code: params.code
784
- })
801
+ code: params.code,
802
+ // 页面先校验两次输入完全一致,SDK 保持原有重置参数。
803
+ password_confirmation: params.password
804
+ }),
805
+ options: webposPasswordResetOptions
785
806
  },
786
807
  resetPasswordByPhone: {
787
808
  url: '/auth/mobile/reset-password',
@@ -4,6 +4,8 @@ import { RegisterParams, LoginParams, OAuthLoginParams, SendVerificationCodePara
4
4
  import { ApiCaller } from './config';
5
5
  export * from './types';
6
6
  export * from './config';
7
+ export { validatePassword } from './utils';
8
+ export type { PasswordValidationOptions } from './utils';
7
9
  /**
8
10
  * 注册登录解决方案实现
9
11
  */
@@ -4,9 +4,16 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  var _exportNames = {
7
- RegisterAndLoginImpl: true
7
+ RegisterAndLoginImpl: true,
8
+ validatePassword: true
8
9
  };
9
10
  exports.RegisterAndLoginImpl = void 0;
11
+ Object.defineProperty(exports, "validatePassword", {
12
+ enumerable: true,
13
+ get: function () {
14
+ return _utils.validatePassword;
15
+ }
16
+ });
10
17
  var _BaseModule = require("../../modules/BaseModule");
11
18
  var _types = require("./types");
12
19
  Object.keys(_types).forEach(function (key) {
@@ -32,6 +39,7 @@ Object.keys(_config).forEach(function (key) {
32
39
  }
33
40
  });
34
41
  });
42
+ var _utils = require("./utils");
35
43
  /**
36
44
  * 注册登录解决方案实现
37
45
  */
@@ -10,10 +10,18 @@ export declare function validateEmail(email: string): boolean;
10
10
  * 验证手机号格式(支持多种国际格式)
11
11
  */
12
12
  export declare function validatePhone(phone: string): boolean;
13
- /**
14
- * 验证密码强度
15
- */
16
- export declare function validatePassword(password: string): {
13
+ export interface PasswordValidationOptions {
14
+ minLength?: number;
15
+ maxLength?: number;
16
+ requireLowercase?: boolean;
17
+ requireUppercase?: boolean;
18
+ requireNumber?: boolean;
19
+ requireSpecialCharacters?: boolean;
20
+ specialCharactersPattern?: RegExp;
21
+ messages?: Partial<Record<'minLength' | 'maxLength' | 'requireLowercase' | 'requireUppercase' | 'requireNumber' | 'requireSpecialCharacters', string>>;
22
+ }
23
+ /** 验证密码强度;不传 options 时保持原有规则与返回格式。 */
24
+ export declare function validatePassword(password: string, options?: PasswordValidationOptions): {
17
25
  isValid: boolean;
18
26
  errors: string[];
19
27
  };
@@ -49,29 +49,36 @@ function validatePhone(phone) {
49
49
  const phoneRegex = /^(\+\d{1,3}[- ]?)?\d{10,14}$/;
50
50
  return phoneRegex.test(cleanPhone);
51
51
  }
52
-
53
- /**
54
- * 验证密码强度
55
- */
56
- function validatePassword(password) {
52
+ /** 验证密码强度;不传 options 时保持原有规则与返回格式。 */
53
+ function validatePassword(password, options = {}) {
57
54
  const errors = [];
58
- if (password.length < 8) {
59
- errors.push('密码长度至少为8位');
55
+ const {
56
+ minLength = 8,
57
+ maxLength = 128,
58
+ requireLowercase = true,
59
+ requireUppercase = true,
60
+ requireNumber = true,
61
+ requireSpecialCharacters = true,
62
+ specialCharactersPattern = /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/,
63
+ messages = {}
64
+ } = options;
65
+ if (password.length < minLength) {
66
+ errors.push(messages.minLength ?? `密码长度至少为${minLength}位`);
60
67
  }
61
- if (password.length > 128) {
62
- errors.push('密码长度不能超过128位');
68
+ if (password.length > maxLength) {
69
+ errors.push(messages.maxLength ?? `密码长度不能超过${maxLength}位`);
63
70
  }
64
- if (!/[a-z]/.test(password)) {
65
- errors.push('密码必须包含至少一个小写字母');
71
+ if (requireLowercase && !/[a-z]/.test(password)) {
72
+ errors.push(messages.requireLowercase ?? '密码必须包含至少一个小写字母');
66
73
  }
67
- if (!/[A-Z]/.test(password)) {
68
- errors.push('密码必须包含至少一个大写字母');
74
+ if (requireUppercase && !/[A-Z]/.test(password)) {
75
+ errors.push(messages.requireUppercase ?? '密码必须包含至少一个大写字母');
69
76
  }
70
- if (!/\d/.test(password)) {
71
- errors.push('密码必须包含至少一个数字');
77
+ if (requireNumber && !/\d/.test(password)) {
78
+ errors.push(messages.requireNumber ?? '密码必须包含至少一个数字');
72
79
  }
73
- if (!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)) {
74
- errors.push('密码必须包含至少一个特殊字符');
80
+ if (requireSpecialCharacters && !specialCharactersPattern.test(password)) {
81
+ errors.push(messages.requireSpecialCharacters ?? '密码必须包含至少一个特殊字符');
75
82
  }
76
83
  return {
77
84
  isValid: errors.length === 0,
@@ -105,6 +105,8 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
105
105
  private groupBookingsByResource;
106
106
  private isBookingMatchedResource;
107
107
  private sortMatchedBookings;
108
+ /** 已完成:按订单创建时间降序,避免实时追加和重新加载导致显示顺序不同。 */
109
+ private sortCompletedBookings;
108
110
  /** Unpaid:与 Current 重合的订单沿用 Current 顺序,其余欠款订单按开始时间降序追加。 */
109
111
  private sortUnpaidBookings;
110
112
  /**
@@ -507,6 +507,15 @@ class SalesImpl extends _BaseModule.BaseModule {
507
507
  });
508
508
  }
509
509
 
510
+ /** 已完成:按订单创建时间降序,避免实时追加和重新加载导致显示顺序不同。 */
511
+ sortCompletedBookings(bookings) {
512
+ const createdAt = booking => {
513
+ const timestamp = (0, _dayjs.default)(booking.order?.created_at || '').valueOf();
514
+ return Number.isFinite(timestamp) ? timestamp : 0;
515
+ };
516
+ return [...bookings].sort((left, right) => createdAt(right) - createdAt(left));
517
+ }
518
+
510
519
  /** Unpaid:与 Current 重合的订单沿用 Current 顺序,其余欠款订单按开始时间降序追加。 */
511
520
  sortUnpaidBookings(bookings, currentBookings) {
512
521
  const currentOrderIndexes = new Map(currentBookings.map((booking, index) => [String(booking.order.order_id), index]));
@@ -881,7 +890,7 @@ class SalesImpl extends _BaseModule.BaseModule {
881
890
  const bookings = this.pickBookingsForCurrentPoint(current, this.normalizeResourceBookings(current, deviceCurrent, matchedBookingList), {
882
891
  includeAllFuture: true
883
892
  });
884
- const completedBookings = completedBookingList.map(booking => {
893
+ const completedBookings = this.sortCompletedBookings(completedBookingList).map(booking => {
885
894
  return {
886
895
  ...booking,
887
896
  status: 'compelete',
@@ -283,10 +283,9 @@ function assertAvailabilityCatalogProductIds(productIds, context) {
283
283
  });
284
284
  }
285
285
  }
286
- function normalizeResourceType(_value) {
287
- // 当前业务只支持每个资源组选择一个具体资源。
288
- // 保留公共联合类型以兼容已有调用方,但暂不启用 multiple/capacity 分支。
289
- return 'single';
286
+ function normalizeResourceType(value) {
287
+ // 预约是否独占与每组选择几个资源是两个独立配置。
288
+ return value === 'multiple' || value === 'capacity' ? value : 'single';
290
289
  }
291
290
  function resolveProductKind(product) {
292
291
  if (product.duration || product.service_duration) return 'duration';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.3.137",
4
+ "version": "2.3.139",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",