@pisell/pisellos 2.1.38 → 2.1.40
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.
- package/dist/effects/index.d.ts +1 -0
- package/dist/effects/index.js +29 -6
- package/dist/modules/Account/index.js +2 -3
- package/dist/modules/BaseModule.d.ts +3 -0
- package/dist/modules/BaseModule.js +15 -0
- package/dist/modules/Customer/index.js +10 -11
- package/dist/modules/Customer/types.d.ts +2 -2
- package/dist/modules/Customer/types.js +2 -2
- package/dist/modules/Discount/index.js +1 -1
- package/dist/modules/Guests/index.js +9 -9
- package/dist/modules/Order/index.js +5 -5
- package/dist/modules/Order/types.d.ts +1 -0
- package/dist/modules/Payment/index.js +17 -17
- package/dist/modules/Payment/walletpass.js +4 -1
- package/dist/modules/Product/index.d.ts +1 -1
- package/dist/modules/ProductList/index.js +2 -3
- package/dist/modules/Resource/index.js +1 -1
- package/dist/modules/Rules/index.js +2 -3
- package/dist/plugins/request.d.ts +1 -0
- package/dist/solution/BookingByStep/index.d.ts +6 -2
- package/dist/solution/BookingByStep/index.js +33 -9
- package/dist/solution/BookingTicket/index.d.ts +4 -0
- package/dist/solution/BookingTicket/index.js +17 -8
- package/dist/solution/BookingTicket/utils/scan/index.d.ts +4 -0
- package/dist/solution/BookingTicket/utils/scan/index.js +25 -16
- package/dist/solution/BuyTickets/index.js +7 -8
- package/dist/solution/Checkout/index.js +35 -35
- package/dist/solution/RegisterAndLogin/config.d.ts +87 -0
- package/dist/solution/RegisterAndLogin/config.js +792 -0
- package/dist/solution/RegisterAndLogin/index.d.ts +189 -0
- package/dist/solution/RegisterAndLogin/index.js +2667 -0
- package/dist/solution/RegisterAndLogin/types.d.ts +444 -0
- package/dist/solution/RegisterAndLogin/types.js +231 -0
- package/dist/solution/RegisterAndLogin/utils.d.ts +95 -0
- package/dist/solution/RegisterAndLogin/utils.js +322 -0
- package/dist/solution/ShopDiscount/index.js +36 -19
- package/dist/solution/index.d.ts +1 -0
- package/dist/solution/index.js +1 -0
- package/dist/types/index.d.ts +1 -0
- package/lib/effects/index.d.ts +1 -0
- package/lib/effects/index.js +13 -0
- package/lib/modules/Account/index.js +2 -3
- package/lib/modules/BaseModule.d.ts +3 -0
- package/lib/modules/BaseModule.js +9 -0
- package/lib/modules/Customer/index.js +10 -11
- package/lib/modules/Customer/types.d.ts +2 -2
- package/lib/modules/Customer/types.js +2 -2
- package/lib/modules/Discount/index.js +1 -1
- package/lib/modules/Guests/index.js +9 -9
- package/lib/modules/Order/index.js +6 -3
- package/lib/modules/Order/types.d.ts +1 -0
- package/lib/modules/Payment/index.js +16 -16
- package/lib/modules/Payment/walletpass.js +3 -1
- package/lib/modules/Product/index.d.ts +1 -1
- package/lib/modules/ProductList/index.js +2 -3
- package/lib/modules/Resource/index.js +1 -1
- package/lib/modules/Rules/index.js +2 -3
- package/lib/plugins/request.d.ts +1 -0
- package/lib/solution/BookingByStep/index.d.ts +6 -2
- package/lib/solution/BookingByStep/index.js +10 -3
- package/lib/solution/BookingTicket/index.d.ts +4 -0
- package/lib/solution/BookingTicket/index.js +12 -6
- package/lib/solution/BookingTicket/utils/scan/index.d.ts +4 -0
- package/lib/solution/BookingTicket/utils/scan/index.js +7 -1
- package/lib/solution/BuyTickets/index.js +7 -8
- package/lib/solution/Checkout/index.js +34 -34
- package/lib/solution/RegisterAndLogin/config.d.ts +87 -0
- package/lib/solution/RegisterAndLogin/config.js +594 -0
- package/lib/solution/RegisterAndLogin/index.d.ts +189 -0
- package/lib/solution/RegisterAndLogin/index.js +1593 -0
- package/lib/solution/RegisterAndLogin/types.d.ts +444 -0
- package/lib/solution/RegisterAndLogin/types.js +78 -0
- package/lib/solution/RegisterAndLogin/utils.d.ts +95 -0
- package/lib/solution/RegisterAndLogin/utils.js +279 -0
- package/lib/solution/ShopDiscount/index.js +19 -11
- package/lib/solution/index.d.ts +1 -0
- package/lib/solution/index.js +2 -0
- package/lib/types/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 注册登录工具函数
|
|
3
|
+
*/
|
|
4
|
+
import { VerificationCodeType, OAuthProvider } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* 验证邮箱格式
|
|
7
|
+
*/
|
|
8
|
+
export declare function validateEmail(email: string): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* 验证手机号格式(支持多种国际格式)
|
|
11
|
+
*/
|
|
12
|
+
export declare function validatePhone(phone: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* 验证密码强度
|
|
15
|
+
*/
|
|
16
|
+
export declare function validatePassword(password: string): {
|
|
17
|
+
isValid: boolean;
|
|
18
|
+
errors: string[];
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* 验证验证码格式
|
|
22
|
+
*/
|
|
23
|
+
export declare function validateVerificationCode(code: string, type: VerificationCodeType): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* 格式化手机号显示
|
|
26
|
+
*/
|
|
27
|
+
export declare function formatPhoneDisplay(phone: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* 格式化邮箱显示(隐藏部分字符)
|
|
30
|
+
*/
|
|
31
|
+
export declare function formatEmailDisplay(email: string, maskLength?: number): string;
|
|
32
|
+
/**
|
|
33
|
+
* 生成随机字符串(用于状态参数等)
|
|
34
|
+
*/
|
|
35
|
+
export declare function generateRandomString(length?: number): string;
|
|
36
|
+
/**
|
|
37
|
+
* 获取 OAuth 提供商的显示名称
|
|
38
|
+
*/
|
|
39
|
+
export declare function getOAuthProviderDisplayName(provider: OAuthProvider): string;
|
|
40
|
+
/**
|
|
41
|
+
* 获取 OAuth 提供商的图标 URL
|
|
42
|
+
*/
|
|
43
|
+
export declare function getOAuthProviderIconUrl(provider: OAuthProvider): string;
|
|
44
|
+
/**
|
|
45
|
+
* 检查是否在移动设备上
|
|
46
|
+
*/
|
|
47
|
+
export declare function isMobileDevice(): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* 检查是否支持 WebAuthn
|
|
50
|
+
*/
|
|
51
|
+
export declare function isWebAuthnSupported(): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* 检查是否在 iOS 设备上
|
|
54
|
+
*/
|
|
55
|
+
export declare function isIOSDevice(): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* 检查是否在 Android 设备上
|
|
58
|
+
*/
|
|
59
|
+
export declare function isAndroidDevice(): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* 获取设备类型
|
|
62
|
+
*/
|
|
63
|
+
export declare function getDeviceType(): 'desktop' | 'mobile' | 'tablet';
|
|
64
|
+
/**
|
|
65
|
+
* 防抖函数
|
|
66
|
+
*/
|
|
67
|
+
export declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => void;
|
|
68
|
+
/**
|
|
69
|
+
* 节流函数
|
|
70
|
+
*/
|
|
71
|
+
export declare function throttle<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => void;
|
|
72
|
+
/**
|
|
73
|
+
* 深拷贝对象
|
|
74
|
+
*/
|
|
75
|
+
export declare function deepClone<T>(obj: T): T;
|
|
76
|
+
/**
|
|
77
|
+
* 安全的 JSON 解析
|
|
78
|
+
*/
|
|
79
|
+
export declare function safeJsonParse<T = any>(jsonString: string, defaultValue: T): T;
|
|
80
|
+
/**
|
|
81
|
+
* 安全的 JSON 字符串化
|
|
82
|
+
*/
|
|
83
|
+
export declare function safeJsonStringify(obj: any, defaultValue?: string): string;
|
|
84
|
+
/**
|
|
85
|
+
* 格式化时间戳为可读时间
|
|
86
|
+
*/
|
|
87
|
+
export declare function formatTimestamp(timestamp: number, format?: string): string;
|
|
88
|
+
/**
|
|
89
|
+
* 计算两个时间戳之间的差值(秒)
|
|
90
|
+
*/
|
|
91
|
+
export declare function getTimeDifference(timestamp1: number, timestamp2: number): number;
|
|
92
|
+
/**
|
|
93
|
+
* 检查时间戳是否过期
|
|
94
|
+
*/
|
|
95
|
+
export declare function isTimestampExpired(timestamp: number, expirationTime?: number): boolean;
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
3
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
4
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
5
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
6
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
7
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
8
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
9
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
10
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
11
|
+
/**
|
|
12
|
+
* 注册登录工具函数
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { VerificationCodeType, OAuthProvider } from "./types";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 验证邮箱格式
|
|
19
|
+
*/
|
|
20
|
+
export function validateEmail(email) {
|
|
21
|
+
var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
22
|
+
return emailRegex.test(email);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 验证手机号格式(支持多种国际格式)
|
|
27
|
+
*/
|
|
28
|
+
export function validatePhone(phone) {
|
|
29
|
+
// 移除所有非数字字符(除了 + 号)
|
|
30
|
+
var cleanPhone = phone.replace(/[^\d+]/g, '');
|
|
31
|
+
|
|
32
|
+
// 基本的手机号验证规则
|
|
33
|
+
var phoneRegex = /^(\+\d{1,3}[- ]?)?\d{10,14}$/;
|
|
34
|
+
return phoneRegex.test(cleanPhone);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 验证密码强度
|
|
39
|
+
*/
|
|
40
|
+
export function validatePassword(password) {
|
|
41
|
+
var errors = [];
|
|
42
|
+
if (password.length < 8) {
|
|
43
|
+
errors.push('密码长度至少为8位');
|
|
44
|
+
}
|
|
45
|
+
if (password.length > 128) {
|
|
46
|
+
errors.push('密码长度不能超过128位');
|
|
47
|
+
}
|
|
48
|
+
if (!/[a-z]/.test(password)) {
|
|
49
|
+
errors.push('密码必须包含至少一个小写字母');
|
|
50
|
+
}
|
|
51
|
+
if (!/[A-Z]/.test(password)) {
|
|
52
|
+
errors.push('密码必须包含至少一个大写字母');
|
|
53
|
+
}
|
|
54
|
+
if (!/\d/.test(password)) {
|
|
55
|
+
errors.push('密码必须包含至少一个数字');
|
|
56
|
+
}
|
|
57
|
+
if (!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)) {
|
|
58
|
+
errors.push('密码必须包含至少一个特殊字符');
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
isValid: errors.length === 0,
|
|
62
|
+
errors: errors
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 验证验证码格式
|
|
68
|
+
*/
|
|
69
|
+
export function validateVerificationCode(code, type) {
|
|
70
|
+
// 移除所有空格
|
|
71
|
+
var cleanCode = code.replace(/\s/g, '');
|
|
72
|
+
switch (type) {
|
|
73
|
+
case VerificationCodeType.EMAIL:
|
|
74
|
+
case VerificationCodeType.SMS:
|
|
75
|
+
// 通常是4-8位数字
|
|
76
|
+
return /^\d{4,8}$/.test(cleanCode);
|
|
77
|
+
default:
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 格式化手机号显示
|
|
84
|
+
*/
|
|
85
|
+
export function formatPhoneDisplay(phone) {
|
|
86
|
+
// 移除所有非数字字符(除了 + 号)
|
|
87
|
+
var cleanPhone = phone.replace(/[^\d+]/g, '');
|
|
88
|
+
|
|
89
|
+
// 如果是中国手机号(11位数字)
|
|
90
|
+
if (/^\d{11}$/.test(cleanPhone)) {
|
|
91
|
+
return cleanPhone.replace(/(\d{3})(\d{4})(\d{4})/, '$1 $2 $3');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 如果是国际号码(以 + 开头)
|
|
95
|
+
if (cleanPhone.startsWith('+')) {
|
|
96
|
+
return cleanPhone;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 其他格式保持原样
|
|
100
|
+
return phone;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 格式化邮箱显示(隐藏部分字符)
|
|
105
|
+
*/
|
|
106
|
+
export function formatEmailDisplay(email) {
|
|
107
|
+
var maskLength = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3;
|
|
108
|
+
var _email$split = email.split('@'),
|
|
109
|
+
_email$split2 = _slicedToArray(_email$split, 2),
|
|
110
|
+
localPart = _email$split2[0],
|
|
111
|
+
domain = _email$split2[1];
|
|
112
|
+
if (!localPart || !domain) {
|
|
113
|
+
return email;
|
|
114
|
+
}
|
|
115
|
+
if (localPart.length <= maskLength * 2) {
|
|
116
|
+
return email;
|
|
117
|
+
}
|
|
118
|
+
var visibleStart = localPart.substring(0, maskLength);
|
|
119
|
+
var visibleEnd = localPart.substring(localPart.length - maskLength);
|
|
120
|
+
var maskedPart = '*'.repeat(localPart.length - maskLength * 2);
|
|
121
|
+
return "".concat(visibleStart).concat(maskedPart).concat(visibleEnd, "@").concat(domain);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* 生成随机字符串(用于状态参数等)
|
|
126
|
+
*/
|
|
127
|
+
export function generateRandomString() {
|
|
128
|
+
var length = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 32;
|
|
129
|
+
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
130
|
+
var result = '';
|
|
131
|
+
for (var i = 0; i < length; i++) {
|
|
132
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* 获取 OAuth 提供商的显示名称
|
|
139
|
+
*/
|
|
140
|
+
export function getOAuthProviderDisplayName(provider) {
|
|
141
|
+
var displayNames = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, OAuthProvider.FACEBOOK, 'Facebook'), OAuthProvider.APPLE, 'Apple'), OAuthProvider.GOOGLE, 'Google'), OAuthProvider.WECHAT, '微信'), OAuthProvider.GITHUB, 'GitHub');
|
|
142
|
+
return displayNames[provider] || provider;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 获取 OAuth 提供商的图标 URL
|
|
147
|
+
*/
|
|
148
|
+
export function getOAuthProviderIconUrl(provider) {
|
|
149
|
+
var iconUrls = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, OAuthProvider.FACEBOOK, 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/facebook.svg'), OAuthProvider.APPLE, 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/apple.svg'), OAuthProvider.GOOGLE, 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/google.svg'), OAuthProvider.WECHAT, 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/wechat.svg'), OAuthProvider.GITHUB, 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/github.svg');
|
|
150
|
+
return iconUrls[provider] || '';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* 检查是否在移动设备上
|
|
155
|
+
*/
|
|
156
|
+
export function isMobileDevice() {
|
|
157
|
+
if (typeof window === 'undefined') {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* 检查是否支持 WebAuthn
|
|
165
|
+
*/
|
|
166
|
+
export function isWebAuthnSupported() {
|
|
167
|
+
if (typeof window === 'undefined') {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
return !!(navigator.credentials && navigator.credentials.create);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* 检查是否在 iOS 设备上
|
|
175
|
+
*/
|
|
176
|
+
export function isIOSDevice() {
|
|
177
|
+
if (typeof window === 'undefined') {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
return /iPad|iPhone|iPod/.test(navigator.userAgent);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* 检查是否在 Android 设备上
|
|
185
|
+
*/
|
|
186
|
+
export function isAndroidDevice() {
|
|
187
|
+
if (typeof window === 'undefined') {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
return /Android/.test(navigator.userAgent);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* 获取设备类型
|
|
195
|
+
*/
|
|
196
|
+
export function getDeviceType() {
|
|
197
|
+
if (typeof window === 'undefined') {
|
|
198
|
+
return 'desktop';
|
|
199
|
+
}
|
|
200
|
+
var userAgent = navigator.userAgent;
|
|
201
|
+
if (/iPad/.test(userAgent)) {
|
|
202
|
+
return 'tablet';
|
|
203
|
+
}
|
|
204
|
+
if (/Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)) {
|
|
205
|
+
return 'mobile';
|
|
206
|
+
}
|
|
207
|
+
return 'desktop';
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* 防抖函数
|
|
212
|
+
*/
|
|
213
|
+
export function debounce(func, wait) {
|
|
214
|
+
var timeout = null;
|
|
215
|
+
return function () {
|
|
216
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
217
|
+
args[_key] = arguments[_key];
|
|
218
|
+
}
|
|
219
|
+
if (timeout) {
|
|
220
|
+
clearTimeout(timeout);
|
|
221
|
+
}
|
|
222
|
+
timeout = setTimeout(function () {
|
|
223
|
+
func.apply(void 0, args);
|
|
224
|
+
}, wait);
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* 节流函数
|
|
230
|
+
*/
|
|
231
|
+
export function throttle(func, wait) {
|
|
232
|
+
var lastTime = 0;
|
|
233
|
+
return function () {
|
|
234
|
+
var now = Date.now();
|
|
235
|
+
if (now - lastTime >= wait) {
|
|
236
|
+
lastTime = now;
|
|
237
|
+
func.apply(void 0, arguments);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* 深拷贝对象
|
|
244
|
+
*/
|
|
245
|
+
export function deepClone(obj) {
|
|
246
|
+
if (obj === null || _typeof(obj) !== 'object') {
|
|
247
|
+
return obj;
|
|
248
|
+
}
|
|
249
|
+
if (obj instanceof Date) {
|
|
250
|
+
return new Date(obj.getTime());
|
|
251
|
+
}
|
|
252
|
+
if (obj instanceof Array) {
|
|
253
|
+
return obj.map(function (item) {
|
|
254
|
+
return deepClone(item);
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
if (_typeof(obj) === 'object') {
|
|
258
|
+
var cloned = {};
|
|
259
|
+
for (var key in obj) {
|
|
260
|
+
if (obj.hasOwnProperty(key)) {
|
|
261
|
+
cloned[key] = deepClone(obj[key]);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return cloned;
|
|
265
|
+
}
|
|
266
|
+
return obj;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* 安全的 JSON 解析
|
|
271
|
+
*/
|
|
272
|
+
export function safeJsonParse(jsonString, defaultValue) {
|
|
273
|
+
try {
|
|
274
|
+
return JSON.parse(jsonString);
|
|
275
|
+
} catch (error) {
|
|
276
|
+
console.warn('JSON 解析失败:', error);
|
|
277
|
+
return defaultValue;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* 安全的 JSON 字符串化
|
|
283
|
+
*/
|
|
284
|
+
export function safeJsonStringify(obj) {
|
|
285
|
+
var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '{}';
|
|
286
|
+
try {
|
|
287
|
+
return JSON.stringify(obj);
|
|
288
|
+
} catch (error) {
|
|
289
|
+
console.warn('JSON 字符串化失败:', error);
|
|
290
|
+
return defaultValue;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* 格式化时间戳为可读时间
|
|
296
|
+
*/
|
|
297
|
+
export function formatTimestamp(timestamp) {
|
|
298
|
+
var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'YYYY-MM-DD HH:mm:ss';
|
|
299
|
+
var date = new Date(timestamp);
|
|
300
|
+
var year = date.getFullYear();
|
|
301
|
+
var month = String(date.getMonth() + 1).padStart(2, '0');
|
|
302
|
+
var day = String(date.getDate()).padStart(2, '0');
|
|
303
|
+
var hours = String(date.getHours()).padStart(2, '0');
|
|
304
|
+
var minutes = String(date.getMinutes()).padStart(2, '0');
|
|
305
|
+
var seconds = String(date.getSeconds()).padStart(2, '0');
|
|
306
|
+
return format.replace('YYYY', year.toString()).replace('MM', month).replace('DD', day).replace('HH', hours).replace('mm', minutes).replace('ss', seconds);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* 计算两个时间戳之间的差值(秒)
|
|
311
|
+
*/
|
|
312
|
+
export function getTimeDifference(timestamp1, timestamp2) {
|
|
313
|
+
return Math.abs(timestamp1 - timestamp2) / 1000;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* 检查时间戳是否过期
|
|
318
|
+
*/
|
|
319
|
+
export function isTimestampExpired(timestamp) {
|
|
320
|
+
var expirationTime = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5 * 60 * 1000;
|
|
321
|
+
return Date.now() - timestamp > expirationTime;
|
|
322
|
+
}
|
|
@@ -25,7 +25,6 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
|
|
|
25
25
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
26
26
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
27
27
|
import { BaseModule } from "../../modules/BaseModule";
|
|
28
|
-
import { ShopDiscountHooks } from "./types";
|
|
29
28
|
import { DiscountModule } from "../../modules/Discount";
|
|
30
29
|
import { RulesModule } from "../../modules/Rules";
|
|
31
30
|
import Decimal from 'decimal.js';
|
|
@@ -104,7 +103,7 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
104
103
|
(_this$store$rules = this.store.rules) === null || _this$store$rules === void 0 || _this$store$rules.destroy();
|
|
105
104
|
this.core.effects.offByModuleDestroy(this.name);
|
|
106
105
|
_context2.next = 7;
|
|
107
|
-
return this.core.effects.emit(
|
|
106
|
+
return this.core.effects.emit("".concat(this.name, ":onDestroy"), {});
|
|
108
107
|
case 7:
|
|
109
108
|
console.log('[ShopDiscount] 已销毁');
|
|
110
109
|
case 8:
|
|
@@ -192,7 +191,7 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
192
191
|
key: "registerEventListeners",
|
|
193
192
|
value: function registerEventListeners() {
|
|
194
193
|
var _this2 = this;
|
|
195
|
-
this.core.effects.
|
|
194
|
+
this.core.effects.only("".concat(this.name, ":onCustomerChange"), function (customer) {
|
|
196
195
|
var _this2$options$otherP;
|
|
197
196
|
if ((_this2$options$otherP = _this2.options.otherParams) !== null && _this2$options$otherP !== void 0 && _this2$options$otherP.cacheId && _this2.getDiscountList().length) {
|
|
198
197
|
return;
|
|
@@ -223,7 +222,7 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
223
222
|
}
|
|
224
223
|
this.store.customer = customer;
|
|
225
224
|
_context4.next = 4;
|
|
226
|
-
return this.core.effects.emit(
|
|
225
|
+
return this.core.effects.emit("".concat(this.name, ":onCustomerChange"), customer);
|
|
227
226
|
case 4:
|
|
228
227
|
case "end":
|
|
229
228
|
return _context4.stop();
|
|
@@ -321,7 +320,7 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
321
320
|
key: "scanCode",
|
|
322
321
|
value: function () {
|
|
323
322
|
var _scanCode = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(code, customerId) {
|
|
324
|
-
var _this$store$discount3, resultDiscountList, rulesModule, withScanList, _ref2, newProductList, newDiscountList, isAvailable, _this$options$otherPa6;
|
|
323
|
+
var _this$store$discount3, resultDiscountList, rulesModule, withScanList, currentSelectedDiscountList, _ref2, newProductList, newDiscountList, isAvailable, _this$options$otherPa6;
|
|
325
324
|
return _regeneratorRuntime().wrap(function _callee5$(_context5) {
|
|
326
325
|
while (1) switch (_context5.prev = _context5.next) {
|
|
327
326
|
case 0:
|
|
@@ -364,7 +363,25 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
364
363
|
return _objectSpread(_objectSpread({}, item), {}, {
|
|
365
364
|
isScan: true
|
|
366
365
|
});
|
|
366
|
+
}); // 如果扫回来的券当前有选中的,则不进行计算
|
|
367
|
+
currentSelectedDiscountList = this.getDiscountList().filter(function (n) {
|
|
368
|
+
return n.isSelected;
|
|
367
369
|
});
|
|
370
|
+
if (!(currentSelectedDiscountList.length && currentSelectedDiscountList.some(function (n) {
|
|
371
|
+
return withScanList.some(function (m) {
|
|
372
|
+
return m.id === n.id;
|
|
373
|
+
});
|
|
374
|
+
}))) {
|
|
375
|
+
_context5.next = 16;
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
return _context5.abrupt("return", {
|
|
379
|
+
type: "clientCalc",
|
|
380
|
+
isAvailable: true,
|
|
381
|
+
productList: this.store.productList || [],
|
|
382
|
+
discountList: this.getDiscountList()
|
|
383
|
+
});
|
|
384
|
+
case 16:
|
|
368
385
|
_ref2 = rulesModule.isDiscountListAvailable({
|
|
369
386
|
productList: this.store.productList || [],
|
|
370
387
|
oldDiscountList: this.getDiscountList(),
|
|
@@ -375,27 +392,27 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
375
392
|
discountList: this.getDiscountList()
|
|
376
393
|
}, newProductList = _ref2.productList, newDiscountList = _ref2.discountList, isAvailable = _ref2.isAvailable;
|
|
377
394
|
if (!isAvailable) {
|
|
378
|
-
_context5.next =
|
|
395
|
+
_context5.next = 24;
|
|
379
396
|
break;
|
|
380
397
|
}
|
|
381
398
|
this.setDiscountList(newDiscountList || []);
|
|
382
399
|
this.store.originalDiscountList = newDiscountList || [];
|
|
383
400
|
this.setProductList(newProductList || []);
|
|
384
401
|
if (!(this.isWalkIn() && resultDiscountList.length && ((_this$options$otherPa6 = this.options.otherParams) === null || _this$options$otherPa6 === void 0 ? void 0 : _this$options$otherPa6.platform) === 'shop')) {
|
|
385
|
-
_context5.next =
|
|
402
|
+
_context5.next = 24;
|
|
386
403
|
break;
|
|
387
404
|
}
|
|
388
|
-
_context5.next =
|
|
405
|
+
_context5.next = 24;
|
|
389
406
|
return this.getCustomerWallet(resultDiscountList[0].customer_id);
|
|
390
|
-
case
|
|
407
|
+
case 24:
|
|
391
408
|
return _context5.abrupt("return", {
|
|
392
409
|
type: "clientCalc",
|
|
393
410
|
isAvailable: isAvailable || false,
|
|
394
411
|
productList: newProductList || this.store.productList || [],
|
|
395
412
|
discountList: newDiscountList || this.getDiscountList()
|
|
396
413
|
});
|
|
397
|
-
case
|
|
398
|
-
_context5.prev =
|
|
414
|
+
case 27:
|
|
415
|
+
_context5.prev = 27;
|
|
399
416
|
_context5.t1 = _context5["catch"](0);
|
|
400
417
|
console.error('[ShopDiscount] 扫码出错:', _context5.t1);
|
|
401
418
|
return _context5.abrupt("return", {
|
|
@@ -404,11 +421,11 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
404
421
|
productList: this.store.productList || [],
|
|
405
422
|
discountList: this.getDiscountList()
|
|
406
423
|
});
|
|
407
|
-
case
|
|
424
|
+
case 31:
|
|
408
425
|
case "end":
|
|
409
426
|
return _context5.stop();
|
|
410
427
|
}
|
|
411
|
-
}, _callee5, this, [[0,
|
|
428
|
+
}, _callee5, this, [[0, 27]]);
|
|
412
429
|
}));
|
|
413
430
|
function scanCode(_x4, _x5) {
|
|
414
431
|
return _scanCode.apply(this, arguments);
|
|
@@ -448,7 +465,7 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
448
465
|
while (1) switch (_context6.prev = _context6.next) {
|
|
449
466
|
case 0:
|
|
450
467
|
_context6.next = 2;
|
|
451
|
-
return this.core.effects.emit(
|
|
468
|
+
return this.core.effects.emit("".concat(this.name, ":onDiscountListChange"), discountList);
|
|
452
469
|
case 2:
|
|
453
470
|
case "end":
|
|
454
471
|
return _context6.stop();
|
|
@@ -579,7 +596,7 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
579
596
|
customer = Object.assign({}, (_objectDestructuringEmpty(_result.data), _result.data));
|
|
580
597
|
this.setCustomer(customer);
|
|
581
598
|
_context7.next = 9;
|
|
582
|
-
return this.core.effects.emit(
|
|
599
|
+
return this.core.effects.emit("".concat(this.name, ":onScanCustomerChange"), customer);
|
|
583
600
|
case 9:
|
|
584
601
|
_context7.next = 14;
|
|
585
602
|
break;
|
|
@@ -616,10 +633,10 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
616
633
|
_result2 = this.calcDiscount(this.store.productList);
|
|
617
634
|
cb === null || cb === void 0 || cb(_result2);
|
|
618
635
|
_context8.next = 7;
|
|
619
|
-
return this.core.effects.emit(
|
|
636
|
+
return this.core.effects.emit("".concat(this.name, ":onLoadPrepareCalcResult"), _result2);
|
|
620
637
|
case 7:
|
|
621
638
|
_context8.next = 9;
|
|
622
|
-
return this.core.effects.emit(
|
|
639
|
+
return this.core.effects.emit("".concat(this.name, ":onLoadDiscountList"), newDiscountList);
|
|
623
640
|
case 9:
|
|
624
641
|
case "end":
|
|
625
642
|
return _context8.stop();
|
|
@@ -670,10 +687,10 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
670
687
|
}
|
|
671
688
|
_result3 = this.calcDiscount(this.store.productList);
|
|
672
689
|
_context9.next = 15;
|
|
673
|
-
return this.core.effects.emit(
|
|
690
|
+
return this.core.effects.emit("".concat(this.name, ":onLoadPrepareCalcResult"), _result3);
|
|
674
691
|
case 15:
|
|
675
692
|
_context9.next = 17;
|
|
676
|
-
return this.core.effects.emit(
|
|
693
|
+
return this.core.effects.emit("".concat(this.name, ":onLoadDiscountList"), newDiscountList);
|
|
677
694
|
case 17:
|
|
678
695
|
_context9.next = 22;
|
|
679
696
|
break;
|
package/dist/solution/index.d.ts
CHANGED
package/dist/solution/index.js
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ export interface PisellCore {
|
|
|
40
40
|
effects: {
|
|
41
41
|
on: (event: string, callback: (payload: any) => void) => () => void;
|
|
42
42
|
once: (event: string, callback: (payload: any) => void) => () => void;
|
|
43
|
+
only: (event: string, callback: (payload: any) => void) => () => void;
|
|
43
44
|
off: (event: string, callback: (payload: any) => void) => void;
|
|
44
45
|
emit: (event: string, payload: any, value?: any) => Promise<{
|
|
45
46
|
status: boolean;
|
package/lib/effects/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ type UnsubscribeFunction = () => void;
|
|
|
6
6
|
declare class EffectsManager {
|
|
7
7
|
private listeners;
|
|
8
8
|
on(event: string, callback: EffectCallback): UnsubscribeFunction;
|
|
9
|
+
only(event: string, callback: EffectCallback): UnsubscribeFunction;
|
|
9
10
|
off(event: string, callback: EffectCallback): void;
|
|
10
11
|
offByModuleDestroy(module: string): void;
|
|
11
12
|
once(event: string, callback: EffectCallback): UnsubscribeFunction;
|
package/lib/effects/index.js
CHANGED
|
@@ -35,6 +35,19 @@ var EffectsManager = class {
|
|
|
35
35
|
this.off(event, callback);
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
+
// 设置单例监听器,只能存在一个,新的会替换旧的
|
|
39
|
+
only(event, callback) {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
if (this.listeners.has(event)) {
|
|
42
|
+
(_a = this.listeners.get(event)) == null ? void 0 : _a.clear();
|
|
43
|
+
} else {
|
|
44
|
+
this.listeners.set(event, /* @__PURE__ */ new Set());
|
|
45
|
+
}
|
|
46
|
+
(_b = this.listeners.get(event)) == null ? void 0 : _b.add(callback);
|
|
47
|
+
return () => {
|
|
48
|
+
this.off(event, callback);
|
|
49
|
+
};
|
|
50
|
+
}
|
|
38
51
|
off(event, callback) {
|
|
39
52
|
var _a;
|
|
40
53
|
(_a = this.listeners.get(event)) == null ? void 0 : _a.delete(callback);
|
|
@@ -24,7 +24,6 @@ __export(Account_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(Account_exports);
|
|
26
26
|
var import_BaseModule = require("../BaseModule");
|
|
27
|
-
var import_types = require("./types");
|
|
28
27
|
__reExport(Account_exports, require("./types"), module.exports);
|
|
29
28
|
var AccountModule = class extends import_BaseModule.BaseModule {
|
|
30
29
|
constructor(name, version) {
|
|
@@ -59,7 +58,7 @@ var AccountModule = class extends import_BaseModule.BaseModule {
|
|
|
59
58
|
};
|
|
60
59
|
this.store.accountInfo = account;
|
|
61
60
|
this.store.isLoggedIn = true;
|
|
62
|
-
await this.core.effects.emit(
|
|
61
|
+
await this.core.effects.emit(`${this.name}:onLogin`, account);
|
|
63
62
|
}
|
|
64
63
|
getCurrentAccount() {
|
|
65
64
|
return this.store.accountInfo;
|
|
@@ -72,7 +71,7 @@ var AccountModule = class extends import_BaseModule.BaseModule {
|
|
|
72
71
|
...updates
|
|
73
72
|
};
|
|
74
73
|
await this.core.effects.emit(
|
|
75
|
-
|
|
74
|
+
`${this.name}:onProfileUpdate`,
|
|
76
75
|
this.store.accountInfo
|
|
77
76
|
);
|
|
78
77
|
}
|
|
@@ -14,4 +14,7 @@ export declare class BaseModule {
|
|
|
14
14
|
store: any;
|
|
15
15
|
cacheKey: string[];
|
|
16
16
|
}): void;
|
|
17
|
+
effectsOn(eventType: string, callback: (payload: any) => void): () => void;
|
|
18
|
+
effectsOff(eventType: string, callback: (payload: any) => void): void;
|
|
19
|
+
effectsOnce(eventType: string, callback: (payload: any) => void): () => void;
|
|
17
20
|
}
|
|
@@ -82,6 +82,15 @@ var BaseModule = class {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
+
effectsOn(eventType, callback) {
|
|
86
|
+
return this.core.effects.on(`${this.name}:${eventType}`, callback);
|
|
87
|
+
}
|
|
88
|
+
effectsOff(eventType, callback) {
|
|
89
|
+
return this.core.effects.off(`${this.name}:${eventType}`, callback);
|
|
90
|
+
}
|
|
91
|
+
effectsOnce(eventType, callback) {
|
|
92
|
+
return this.core.effects.once(`${this.name}:${eventType}`, callback);
|
|
93
|
+
}
|
|
85
94
|
};
|
|
86
95
|
// Annotate the CommonJS export names for ESM import in node:
|
|
87
96
|
0 && (module.exports = {
|