@pisell/pisellos 0.10.56 → 0.10.57
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/modules/OpenData/index.js +2 -1
- package/dist/modules/Order/index.d.ts +2 -1
- package/dist/modules/Order/index.js +118 -59
- package/dist/modules/Order/utils/weighedProduct.d.ts +12 -0
- package/dist/modules/Order/utils/weighedProduct.js +94 -0
- package/dist/modules/Order/utils.d.ts +1 -1
- package/dist/modules/Order/utils.js +9 -6
- package/dist/modules/Payment/index.d.ts +0 -5
- package/dist/modules/Payment/index.js +35 -85
- package/dist/modules/ProductList/index.js +18 -5
- package/dist/modules/ResourcePlanner/planner.js +10 -8
- package/dist/modules/Rules/index.js +16 -14
- package/dist/modules/Rules/types.d.ts +2 -0
- package/dist/server/index.js +122 -69
- package/dist/server/modules/floor-plan/index.js +34 -3
- package/dist/server/modules/payment/index.d.ts +25 -6
- package/dist/server/modules/payment/index.js +660 -133
- package/dist/server/test.json +1 -1
- package/dist/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
- package/dist/shared/receipt/customerInvoiceLanguages.js +60 -0
- package/dist/shared/receipt/loadCustomerInvoiceLayout.d.ts +5 -0
- package/dist/shared/receipt/loadCustomerInvoiceLayout.js +46 -4
- package/dist/shared/receipt/small-ticket.d.ts +11 -0
- package/dist/shared/receipt/small-ticket.js +430 -255
- package/dist/shared/receipt/templateVisibility.d.ts +23 -0
- package/dist/shared/receipt/templateVisibility.js +64 -0
- package/dist/solution/BaseSales/index.d.ts +4 -2
- package/dist/solution/BaseSales/index.js +1328 -1214
- package/dist/solution/BaseSales/types.d.ts +5 -1
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +40 -25
- package/dist/solution/BaseSales/utils.js +3 -2
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +4 -1
- package/dist/solution/BookingTicket/index.js +120 -80
- package/dist/solution/OrderInvoicePreview/index.d.ts +10 -0
- package/dist/solution/OrderInvoicePreview/index.js +85 -14
- package/dist/solution/RegisterAndLogin/config.js +54 -11
- package/dist/solution/RegisterAndLogin/index.d.ts +2 -0
- package/dist/solution/RegisterAndLogin/index.js +1 -1
- package/dist/solution/RegisterAndLogin/utils.d.ts +12 -4
- package/dist/solution/RegisterAndLogin/utils.js +36 -16
- package/dist/solution/Sales/index.d.ts +2 -0
- package/dist/solution/Sales/index.js +15 -1
- package/dist/solution/ScanOrder/utils.js +3 -2
- package/dist/solution/UnifiedBookingSales/index.js +12 -13
- package/dist/solution/VenueBooking/index.d.ts +15 -2
- package/dist/solution/VenueBooking/index.js +1062 -785
- package/dist/solution/VenueBooking/types.d.ts +2 -1
- package/dist/solution/VenueBooking/types.js +1 -0
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
- package/dist/solution/VenueBooking/utils/dateSummary.js +7 -4
- package/dist/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
- package/dist/solution/VenueBooking/utils/smartPricing.js +273 -0
- package/dist/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
- package/dist/solution/VenueBooking/utils/timeSlot.js +6 -3
- package/lib/modules/OpenData/index.js +2 -1
- package/lib/modules/Order/index.d.ts +2 -1
- package/lib/modules/Order/index.js +71 -11
- package/lib/modules/Order/utils/weighedProduct.d.ts +12 -0
- package/lib/modules/Order/utils/weighedProduct.js +89 -0
- package/lib/modules/Order/utils.d.ts +1 -1
- package/lib/modules/Order/utils.js +5 -3
- package/lib/modules/Payment/index.d.ts +0 -5
- package/lib/modules/Payment/index.js +3 -28
- package/lib/modules/ProductList/index.js +14 -1
- package/lib/modules/ResourcePlanner/planner.js +10 -8
- package/lib/modules/Rules/index.js +16 -14
- package/lib/modules/Rules/types.d.ts +2 -0
- package/lib/server/index.js +72 -28
- package/lib/server/modules/floor-plan/index.js +29 -1
- package/lib/server/modules/payment/index.d.ts +25 -6
- package/lib/server/modules/payment/index.js +350 -78
- package/lib/server/test.json +1 -1
- package/lib/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
- package/lib/shared/receipt/customerInvoiceLanguages.js +58 -0
- package/lib/shared/receipt/loadCustomerInvoiceLayout.d.ts +5 -0
- package/lib/shared/receipt/loadCustomerInvoiceLayout.js +42 -4
- package/lib/shared/receipt/small-ticket.d.ts +11 -0
- package/lib/shared/receipt/small-ticket.js +234 -30
- package/lib/shared/receipt/templateVisibility.d.ts +23 -0
- package/lib/shared/receipt/templateVisibility.js +63 -0
- package/lib/solution/BaseSales/index.d.ts +4 -2
- package/lib/solution/BaseSales/index.js +79 -18
- package/lib/solution/BaseSales/types.d.ts +5 -1
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +24 -9
- package/lib/solution/BaseSales/utils.js +2 -1
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +4 -1
- package/lib/solution/BookingTicket/index.js +14 -2
- package/lib/solution/OrderInvoicePreview/index.d.ts +10 -0
- package/lib/solution/OrderInvoicePreview/index.js +61 -7
- package/lib/solution/RegisterAndLogin/config.js +57 -11
- package/lib/solution/RegisterAndLogin/index.d.ts +2 -0
- package/lib/solution/RegisterAndLogin/index.js +9 -1
- package/lib/solution/RegisterAndLogin/utils.d.ts +12 -4
- package/lib/solution/RegisterAndLogin/utils.js +24 -17
- package/lib/solution/Sales/index.d.ts +2 -0
- package/lib/solution/Sales/index.js +10 -1
- package/lib/solution/ScanOrder/utils.js +2 -1
- package/lib/solution/UnifiedBookingSales/index.js +5 -6
- package/lib/solution/VenueBooking/index.d.ts +15 -2
- package/lib/solution/VenueBooking/index.js +243 -96
- package/lib/solution/VenueBooking/types.d.ts +2 -1
- package/lib/solution/VenueBooking/types.js +1 -0
- package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
- package/lib/solution/VenueBooking/utils/dateSummary.js +7 -4
- package/lib/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
- package/lib/solution/VenueBooking/utils/smartPricing.js +224 -0
- package/lib/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
- package/lib/solution/VenueBooking/utils/timeSlot.js +5 -2
- package/package.json +1 -1
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.OrderInvoicePreviewImpl = void 0;
|
|
7
7
|
var _BaseModule = require("../../modules/BaseModule");
|
|
8
8
|
var _loadCustomerInvoiceLayout = require("../../shared/receipt/loadCustomerInvoiceLayout");
|
|
9
|
+
var _customerInvoiceLanguages = require("../../shared/receipt/customerInvoiceLanguages");
|
|
9
10
|
var _smallTicket = require("../../shared/receipt/small-ticket");
|
|
10
11
|
var _loadSalesOrderSnapshot = require("../../shared/sales/loadSalesOrderSnapshot");
|
|
11
12
|
var _loadPaymentMethods = require("../../shared/payment/loadPaymentMethods");
|
|
@@ -25,6 +26,8 @@ class OrderInvoicePreviewImpl extends _BaseModule.BaseModule {
|
|
|
25
26
|
disposed = false;
|
|
26
27
|
input;
|
|
27
28
|
activeKey = '';
|
|
29
|
+
// Hosts retain this readonly instance while the same order modal is closed.
|
|
30
|
+
languageSelection;
|
|
28
31
|
pending;
|
|
29
32
|
snapshotCache = new Map();
|
|
30
33
|
constructor(name = 'orderInvoicePreview') {
|
|
@@ -56,7 +59,7 @@ class OrderInvoicePreviewImpl extends _BaseModule.BaseModule {
|
|
|
56
59
|
cache = new Map();
|
|
57
60
|
contextCaches.set(this.request, cache);
|
|
58
61
|
}
|
|
59
|
-
const key = JSON.stringify([input.tenantId, input.shopId, input.identity
|
|
62
|
+
const key = JSON.stringify([input.tenantId, input.shopId, input.identity]);
|
|
60
63
|
const cached = cache.get(key);
|
|
61
64
|
if (cached) return cached;
|
|
62
65
|
const task = Promise.all([this.request.get('/shop/show', {}, {
|
|
@@ -115,6 +118,7 @@ class OrderInvoicePreviewImpl extends _BaseModule.BaseModule {
|
|
|
115
118
|
if (this.state.status === 'ready' && this.state.result) return Promise.resolve(this.state.result);
|
|
116
119
|
}
|
|
117
120
|
if (this.input && this.getScope(this.input) !== this.getScope(input)) this.snapshotCache.clear();
|
|
121
|
+
if (this.languageSelection?.scope !== this.getSelectionScope(input)) this.languageSelection = undefined;
|
|
118
122
|
this.input = input;
|
|
119
123
|
this.activeKey = key;
|
|
120
124
|
const generation = ++this.generation;
|
|
@@ -124,7 +128,7 @@ class OrderInvoicePreviewImpl extends _BaseModule.BaseModule {
|
|
|
124
128
|
error: null
|
|
125
129
|
});
|
|
126
130
|
const task = (async () => {
|
|
127
|
-
const [snapshot, context,
|
|
131
|
+
const [snapshot, context, template] = await Promise.all([this.loadSource(input), this.loadContext(input), (0, _loadCustomerInvoiceLayout.loadCustomerInvoiceTemplate)(this.request, input)]);
|
|
128
132
|
const source = (0, _loadPaymentMethods.withPaymentMethodNames)(snapshot, context.methods);
|
|
129
133
|
const getData = this.core.getPlugin('app')?.getData?.();
|
|
130
134
|
if (getData?.('shop_id') != null && String(getData('shop_id')) !== String(input.shopId)) throw new Error('Invoice shop changed');
|
|
@@ -139,21 +143,30 @@ class OrderInvoicePreviewImpl extends _BaseModule.BaseModule {
|
|
|
139
143
|
} : {})
|
|
140
144
|
};
|
|
141
145
|
if (generation !== this.generation || this.disposed) throw new Error('Invoice request superseded');
|
|
142
|
-
const
|
|
143
|
-
const
|
|
146
|
+
const languageOptions = (0, _customerInvoiceLanguages.resolveCustomerInvoiceLanguages)(template.language, input.locale);
|
|
147
|
+
const remembered = this.languageSelection?.code;
|
|
148
|
+
const selected = languageOptions.find(option => option.code === remembered) || languageOptions[0];
|
|
149
|
+
const locale = selected.locales[0];
|
|
144
150
|
const result = {
|
|
145
|
-
identity: key,
|
|
151
|
+
identity: this.documentIdentity(key, selected.code),
|
|
152
|
+
languageOptions,
|
|
153
|
+
selectedLanguage: selected.code,
|
|
154
|
+
...(selected.locales[1] ? {
|
|
155
|
+
secondaryLocale: selected.locales[1]
|
|
156
|
+
} : {}),
|
|
146
157
|
orderId: input.orderId,
|
|
147
158
|
sourceRevision: input.sourceRevision,
|
|
148
159
|
generatedAt: new Date().toISOString(),
|
|
149
160
|
locale,
|
|
150
161
|
source,
|
|
151
162
|
shop,
|
|
152
|
-
layout,
|
|
163
|
+
layout: template.layout,
|
|
153
164
|
smallTicketData: (0, _smallTicket.buildSmallTicketData)({
|
|
154
165
|
order: source,
|
|
155
166
|
shopInfo: shop,
|
|
156
|
-
locales: [
|
|
167
|
+
locales: [...new Set(languageOptions.flatMap(option => option.locales))],
|
|
168
|
+
includeReceiptKeys: true,
|
|
169
|
+
templateSettings: template.layout
|
|
157
170
|
})
|
|
158
171
|
};
|
|
159
172
|
this.publish({
|
|
@@ -177,6 +190,47 @@ class OrderInvoicePreviewImpl extends _BaseModule.BaseModule {
|
|
|
177
190
|
this.pending = task;
|
|
178
191
|
return task;
|
|
179
192
|
}
|
|
193
|
+
getSelectionScope(input) {
|
|
194
|
+
return JSON.stringify([this.getScope(input), input.orderId]);
|
|
195
|
+
}
|
|
196
|
+
documentIdentity(key, language) {
|
|
197
|
+
return JSON.stringify([key, language]);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Switch only the ready receipt projection; no fetching or rebuilding data. */
|
|
201
|
+
selectLanguage(code) {
|
|
202
|
+
if (this.disposed) throw new Error('Invoice preview disposed');
|
|
203
|
+
const current = this.state.result;
|
|
204
|
+
if (this.state.status !== 'ready' || !current || !this.input) throw new Error('Invoice preview is not ready');
|
|
205
|
+
const currentShop = this.core.getPlugin('app')?.getData?.()?.('shop_id');
|
|
206
|
+
if (currentShop != null && String(currentShop) !== String(this.input.shopId)) throw new Error('Invoice shop changed');
|
|
207
|
+
const selected = current.languageOptions.find(option => option.code === code);
|
|
208
|
+
if (!selected) throw new Error('Invoice language is unavailable');
|
|
209
|
+
this.languageSelection = {
|
|
210
|
+
scope: this.getSelectionScope(this.input),
|
|
211
|
+
code: selected.code
|
|
212
|
+
};
|
|
213
|
+
if (selected.code === current.selectedLanguage) return current;
|
|
214
|
+
const {
|
|
215
|
+
secondaryLocale: _previousSecondary,
|
|
216
|
+
...rest
|
|
217
|
+
} = current;
|
|
218
|
+
const result = {
|
|
219
|
+
...rest,
|
|
220
|
+
identity: this.documentIdentity(this.activeKey, selected.code),
|
|
221
|
+
selectedLanguage: selected.code,
|
|
222
|
+
locale: selected.locales[0],
|
|
223
|
+
...(selected.locales[1] ? {
|
|
224
|
+
secondaryLocale: selected.locales[1]
|
|
225
|
+
} : {})
|
|
226
|
+
};
|
|
227
|
+
this.publish({
|
|
228
|
+
status: 'ready',
|
|
229
|
+
result,
|
|
230
|
+
error: null
|
|
231
|
+
});
|
|
232
|
+
return result;
|
|
233
|
+
}
|
|
180
234
|
retry() {
|
|
181
235
|
if (!this.input) return Promise.reject(new Error('Invoice input is missing'));
|
|
182
236
|
return this.prepare(this.input);
|
|
@@ -305,6 +305,30 @@ function withH5AuthPrefix(config) {
|
|
|
305
305
|
return nextConfig;
|
|
306
306
|
}
|
|
307
307
|
const h5OnlineStoreConfig = withH5AuthPrefix(onlineStoreConfig);
|
|
308
|
+
function withKioskSalesChannel(config) {
|
|
309
|
+
return {
|
|
310
|
+
...config,
|
|
311
|
+
options: params => {
|
|
312
|
+
const options = (typeof config.options === 'function' ? config.options(params) : config.options) || {};
|
|
313
|
+
const headers = typeof options.headers === 'function' ? options.headers(params) : options.headers;
|
|
314
|
+
return {
|
|
315
|
+
...options,
|
|
316
|
+
headers: {
|
|
317
|
+
...headers,
|
|
318
|
+
'Sales-Channel': 'kiosk'
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Kiosk 复用网店顾客认证接口,通过注册(含验证码登录自动注册)请求头标识会员归属渠道。
|
|
326
|
+
const kioskConfig = {
|
|
327
|
+
...h5OnlineStoreConfig,
|
|
328
|
+
emailCodeRegister: withKioskSalesChannel(h5OnlineStoreConfig.emailCodeRegister),
|
|
329
|
+
phoneCodeRegister: withKioskSalesChannel(h5OnlineStoreConfig.phoneCodeRegister),
|
|
330
|
+
phoneCodeLogin: withKioskSalesChannel(h5OnlineStoreConfig.phoneCodeLogin)
|
|
331
|
+
};
|
|
308
332
|
|
|
309
333
|
/**
|
|
310
334
|
* 默认配置(通用配置)
|
|
@@ -564,6 +588,16 @@ const defaultConfig = {
|
|
|
564
588
|
/**
|
|
565
589
|
* webpos 渠道配置
|
|
566
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
|
+
};
|
|
567
601
|
const webposConfig = {
|
|
568
602
|
sendEmailVerificationCode: {
|
|
569
603
|
url: '/auth/email/register-code',
|
|
@@ -686,13 +720,20 @@ const webposConfig = {
|
|
|
686
720
|
})
|
|
687
721
|
},
|
|
688
722
|
checkEmailCode: {
|
|
689
|
-
url: '/
|
|
690
|
-
method: '
|
|
723
|
+
url: '/tenant/account/reset-password/email-code/verify',
|
|
724
|
+
method: 'POST',
|
|
691
725
|
transformParams: params => ({
|
|
692
726
|
email: params.email,
|
|
693
|
-
code: params.code
|
|
694
|
-
|
|
695
|
-
|
|
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
|
|
696
737
|
},
|
|
697
738
|
checkMobileCode: {
|
|
698
739
|
url: '/auth/mobile/check-mobile-code',
|
|
@@ -714,11 +755,12 @@ const webposConfig = {
|
|
|
714
755
|
})
|
|
715
756
|
},
|
|
716
757
|
sendPasswordResetEmail: {
|
|
717
|
-
url: '/
|
|
718
|
-
method: '
|
|
758
|
+
url: '/tenant/account/reset-password/email-code/send',
|
|
759
|
+
method: 'POST',
|
|
719
760
|
transformParams: params => ({
|
|
720
761
|
email: params.email
|
|
721
|
-
})
|
|
762
|
+
}),
|
|
763
|
+
options: webposPasswordResetOptions
|
|
722
764
|
},
|
|
723
765
|
sendPasswordResetSms: {
|
|
724
766
|
url: '/auth/mobile/sms-forget',
|
|
@@ -751,13 +793,16 @@ const webposConfig = {
|
|
|
751
793
|
})
|
|
752
794
|
},
|
|
753
795
|
resetPasswordByEmail: {
|
|
754
|
-
url: '/
|
|
796
|
+
url: '/tenant/account/reset-password/email-code',
|
|
755
797
|
method: 'POST',
|
|
756
798
|
transformParams: params => ({
|
|
757
799
|
email: params.email,
|
|
758
800
|
password: params.password,
|
|
759
|
-
code: params.code
|
|
760
|
-
|
|
801
|
+
code: params.code,
|
|
802
|
+
// 页面先校验两次输入完全一致,SDK 保持原有重置参数。
|
|
803
|
+
password_confirmation: params.password
|
|
804
|
+
}),
|
|
805
|
+
options: webposPasswordResetOptions
|
|
761
806
|
},
|
|
762
807
|
resetPasswordByPhone: {
|
|
763
808
|
url: '/auth/mobile/reset-password',
|
|
@@ -1094,6 +1139,7 @@ const shopWebposConfig = {
|
|
|
1094
1139
|
const channelConfigMap = exports.channelConfigMap = {
|
|
1095
1140
|
'online-store': onlineStoreConfig,
|
|
1096
1141
|
'online-store-h5': h5OnlineStoreConfig,
|
|
1142
|
+
'kiosk': kioskConfig,
|
|
1097
1143
|
'default': defaultConfig,
|
|
1098
1144
|
'webpos': webposConfig,
|
|
1099
1145
|
'shop.webpos': shopWebposConfig
|
|
@@ -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
|
-
|
|
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
|
-
|
|
59
|
-
|
|
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 >
|
|
62
|
-
errors.push(
|
|
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 (
|
|
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',
|
|
@@ -34,6 +34,7 @@ exports.toNonNegativeInt = toNonNegativeInt;
|
|
|
34
34
|
exports.toNonNegativeNumber = toNonNegativeNumber;
|
|
35
35
|
exports.toPositiveString = toPositiveString;
|
|
36
36
|
exports.toPriceString = toPriceString;
|
|
37
|
+
var _weighedProduct = require("../../modules/Order/utils/weighedProduct");
|
|
37
38
|
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
38
39
|
var _decimal = _interopRequireDefault(require("decimal.js"));
|
|
39
40
|
var _utils = require("../../modules/Order/utils");
|
|
@@ -612,7 +613,7 @@ function normalizeOrderProduct(product) {
|
|
|
612
613
|
});
|
|
613
614
|
const composedOriginalPrice = (0, _utils.composeLinePrice)({
|
|
614
615
|
mainPrice: mainOriginalStr,
|
|
615
|
-
bundle: normalizedBundle,
|
|
616
|
+
bundle: Number(productSku.open_sold_weight) === 1 && (0, _manualProductDiscount.hasManualProductDiscountFlag)(metadata) ? (0, _weighedProduct.withOriginalBundleOptionPrices)(normalizedBundle) : normalizedBundle,
|
|
616
617
|
useOriginalBundle: true
|
|
617
618
|
});
|
|
618
619
|
const finalOriginalPrice = (0, _utils.resolveManualOverrideLineOriginalPrice)({
|
|
@@ -55,7 +55,7 @@ var _localClock = require("../../modules/ResourcePlanner/localClock");
|
|
|
55
55
|
var _platform = require("../../utils/platform");
|
|
56
56
|
var _itemRule = require("../../model/strategy/adapter/itemRule");
|
|
57
57
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
58
|
-
const OPEN_DATA_SECTION_CODES = ['sale', 'reservation', 'fulfillment', 'menu', 'workflow', '
|
|
58
|
+
const OPEN_DATA_SECTION_CODES = ['sale', 'reservation', 'fulfillment', 'menu', 'workflow', 'documents', 'basic', 'checkout', 'availability'];
|
|
59
59
|
function normalizePositiveInteger(value) {
|
|
60
60
|
const normalized = Number(value);
|
|
61
61
|
if (!Number.isInteger(normalized) || normalized <= 0) return undefined;
|
|
@@ -283,10 +283,9 @@ function assertAvailabilityCatalogProductIds(productIds, context) {
|
|
|
283
283
|
});
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
|
-
function normalizeResourceType(
|
|
287
|
-
//
|
|
288
|
-
|
|
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';
|
|
@@ -1655,7 +1654,7 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
|
|
|
1655
1654
|
shouldUseCheckoutSyncTask() {
|
|
1656
1655
|
const configured = this.otherParams?.checkoutSyncTaskEnabled;
|
|
1657
1656
|
if (configured === true) return true;
|
|
1658
|
-
const platform =
|
|
1657
|
+
const platform = (0, _platform.normalizeRuntimePlatform)(this.otherParams?.platform);
|
|
1659
1658
|
return !(0, _platform.isCustomerUserPlatform)(platform) && platform !== 'kiosk';
|
|
1660
1659
|
}
|
|
1661
1660
|
|
|
@@ -41,6 +41,11 @@ export declare class VenueBookingImpl extends BaseSalesImpl implements Module {
|
|
|
41
41
|
private customerLoginRefreshIdInFlight;
|
|
42
42
|
private loadAllProductsInFlight;
|
|
43
43
|
private productsLoaded;
|
|
44
|
+
private smartPricingCustomerId;
|
|
45
|
+
private smartPricingProductCatalog;
|
|
46
|
+
private slotPriceMapCache;
|
|
47
|
+
private slotPriceStrategyConfigs;
|
|
48
|
+
private slotPriceScheduleList;
|
|
44
49
|
private loadOpenDataConfigInFlight;
|
|
45
50
|
private static readonly OPEN_DATA_CACHE_TTL;
|
|
46
51
|
private getLoggerContext;
|
|
@@ -69,7 +74,7 @@ export declare class VenueBookingImpl extends BaseSalesImpl implements Module {
|
|
|
69
74
|
private clearLoginEffectListeners;
|
|
70
75
|
private registerLoginEffect;
|
|
71
76
|
private registerCustomerLoginListeners;
|
|
72
|
-
private
|
|
77
|
+
private refreshOrderMarketingForCustomer;
|
|
73
78
|
initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
|
|
74
79
|
destroy(): Promise<void>;
|
|
75
80
|
retryInit(): Promise<void>;
|
|
@@ -82,6 +87,11 @@ export declare class VenueBookingImpl extends BaseSalesImpl implements Module {
|
|
|
82
87
|
passed: boolean | null;
|
|
83
88
|
failures: QuantityCheckResult[];
|
|
84
89
|
};
|
|
90
|
+
private resolveCustomerIdForSmartPricing;
|
|
91
|
+
private buildSmartPricingContext;
|
|
92
|
+
private buildSlotPriceMapForDate;
|
|
93
|
+
/** 规则或客户上下文更新后,同步商品展示、已选时段和订单汇总。 */
|
|
94
|
+
refreshSmartPricing(): Promise<void>;
|
|
85
95
|
loadAllProducts(): Promise<{
|
|
86
96
|
venueProducts: ProductData[];
|
|
87
97
|
addonProducts: ProductData[];
|
|
@@ -167,7 +177,10 @@ export declare class VenueBookingImpl extends BaseSalesImpl implements Module {
|
|
|
167
177
|
onCustomerLogin(params: {
|
|
168
178
|
customerId: number;
|
|
169
179
|
}): Promise<void>;
|
|
170
|
-
|
|
180
|
+
/** 宿主退出登录或以匿名身份重新进入时,清理客户资产并恢复匿名价格。 */
|
|
181
|
+
onCustomerLogout(): Promise<void>;
|
|
182
|
+
private recalculateOrderPricesFromSmartPricing;
|
|
183
|
+
private resetProductPriceForSmartPricing;
|
|
171
184
|
scanCode(code: string, customerId?: number): Promise<{
|
|
172
185
|
isAvailable: boolean;
|
|
173
186
|
isAccepted?: boolean | undefined;
|