@pisell/pisellos 2.3.158 → 2.3.160
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/model/strategy/adapter/promotion/index.js +9 -0
- package/dist/modules/OpenData/types.d.ts +2 -0
- package/dist/server/index.js +12 -1
- package/dist/server/modules/form/index.d.ts +19 -0
- package/dist/server/modules/form/index.js +205 -0
- package/dist/server/modules/form/types.d.ts +13 -0
- package/dist/server/modules/form/types.js +3 -0
- package/dist/server/modules/index.d.ts +3 -0
- package/dist/server/modules/index.js +4 -0
- package/dist/server/modules/order/index.d.ts +2 -0
- package/dist/server/modules/order/index.js +794 -714
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +5 -0
- package/dist/solution/BookingTicket/index.js +33 -4
- package/lib/modules/OpenData/types.d.ts +2 -0
- package/lib/server/index.js +12 -1
- package/lib/server/modules/form/index.d.ts +19 -0
- package/lib/server/modules/form/index.js +73 -0
- package/lib/server/modules/form/types.d.ts +13 -0
- package/lib/server/modules/form/types.js +9 -0
- package/lib/server/modules/index.d.ts +3 -0
- package/lib/server/modules/index.js +15 -1
- package/lib/server/modules/order/index.d.ts +2 -0
- package/lib/server/modules/order/index.js +36 -0
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +5 -0
- package/lib/solution/BookingTicket/index.js +24 -2
- package/package.json +1 -1
|
@@ -328,7 +328,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
328
328
|
date: string;
|
|
329
329
|
status: string;
|
|
330
330
|
week: string;
|
|
331
|
-
weekNum: 0 |
|
|
331
|
+
weekNum: 0 | 1 | 2 | 6 | 3 | 4 | 5;
|
|
332
332
|
}[]>;
|
|
333
333
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
334
334
|
private getScheduleDataByIds;
|
|
@@ -42,6 +42,10 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
42
42
|
*/
|
|
43
43
|
protected getRegisteredModuleNames(): readonly string[];
|
|
44
44
|
protected getSubmitOrderSalesChannel(): string;
|
|
45
|
+
/** 供销售展示层按 booking.resources[].form_id 读取当前多语言表单标题。 */
|
|
46
|
+
getFormTitleMap(): Record<string, Record<string, string> | string>;
|
|
47
|
+
/** 表单定义由 Ably 更新后通知展示层刷新,不改动订单里的历史 metadata。 */
|
|
48
|
+
onFormTitlesChanged(callback: (titles: Record<string, Record<string, string> | string>) => void): () => void;
|
|
45
49
|
/**
|
|
46
50
|
* 业务侧子模块工厂:BookingTicket 自带的 createBookingTicketModule 优先匹配;
|
|
47
51
|
* 未识别的模块名(如 BookingByStep 公共类型)回退到父类工厂。
|
|
@@ -67,6 +71,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
67
71
|
private getShortNumberOrDeviceId;
|
|
68
72
|
private configureIdGeneratorFromOpenData;
|
|
69
73
|
private normalizePositiveInteger;
|
|
74
|
+
private normalizeShortNumberMaximum;
|
|
70
75
|
private normalizeIdPrefix;
|
|
71
76
|
/**
|
|
72
77
|
* 加载销售详情,并在父类基础上把 customer 信息装配到 CustomerModule。
|
|
@@ -51,6 +51,7 @@ import { buildProductOptionStringFromOrderLine } from "../../modules/BookingCont
|
|
|
51
51
|
import { applyBookingsStatus, applyChildBookingStatus, resolveScheduleId, resolveStatusAfterTransition, restoreBookingsStatus, restoreChildBookingStatus } from "./utils/bookingStatus";
|
|
52
52
|
import { resolveBestAddTimePlan as _resolveBestAddTimePlan } from "./utils/resolveBestAddTimePlan";
|
|
53
53
|
import { createUuidV4 } from "../../modules/Order/utils";
|
|
54
|
+
import { FormHooks } from "../../server/modules/form/types";
|
|
54
55
|
var OPEN_DATA_SECTION_CODES = ['sale', 'reservation', 'fulfillment', 'menu', 'workflow', 'documents'];
|
|
55
56
|
var OPEN_DATA_CACHE_TTL = 5 * 60 * 1000;
|
|
56
57
|
var USER_PLATFORM = ['pc', 'h5'];
|
|
@@ -206,6 +207,21 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
|
|
|
206
207
|
return !channel || channel === 'system' ? 'pos' : channel;
|
|
207
208
|
}
|
|
208
209
|
|
|
210
|
+
/** 供销售展示层按 booking.resources[].form_id 读取当前多语言表单标题。 */
|
|
211
|
+
}, {
|
|
212
|
+
key: "getFormTitleMap",
|
|
213
|
+
value: function getFormTitleMap() {
|
|
214
|
+
var _this$core2, _this$core2$getTitleM;
|
|
215
|
+
return ((_this$core2 = this.core) === null || _this$core2 === void 0 || (_this$core2 = _this$core2.server) === null || _this$core2 === void 0 || (_this$core2 = _this$core2.form) === null || _this$core2 === void 0 || (_this$core2$getTitleM = _this$core2.getTitleMap) === null || _this$core2$getTitleM === void 0 ? void 0 : _this$core2$getTitleM.call(_this$core2)) || {};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** 表单定义由 Ably 更新后通知展示层刷新,不改动订单里的历史 metadata。 */
|
|
219
|
+
}, {
|
|
220
|
+
key: "onFormTitlesChanged",
|
|
221
|
+
value: function onFormTitlesChanged(callback) {
|
|
222
|
+
return this.core.effects.on(FormHooks.onChanged, callback);
|
|
223
|
+
}
|
|
224
|
+
|
|
209
225
|
/**
|
|
210
226
|
* 业务侧子模块工厂:BookingTicket 自带的 createBookingTicketModule 优先匹配;
|
|
211
227
|
* 未识别的模块名(如 BookingByStep 公共类型)回退到父类工厂。
|
|
@@ -590,7 +606,7 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
|
|
|
590
606
|
value: function () {
|
|
591
607
|
var _configureIdGeneratorFromOpenData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9() {
|
|
592
608
|
var _openDataConfig, _openDataConfig2, _openDataConfig3, _openDataConfig4, _openDataConfig5, _openDataConfig6;
|
|
593
|
-
var idGenerator, openDataConfig, receiptSequenceLength, receiptSequenceStart, prefix, shopOrderPrefix, resetReceiptSequenceDaily, operatingDayBoundary, deviceId, businessCode, _openDataConfig7;
|
|
609
|
+
var idGenerator, openDataConfig, receiptSequenceLength, receiptSequenceStart, prefix, shopOrderPrefix, resetReceiptSequenceDaily, operatingDayBoundary, deviceId, businessCode, _openDataConfig7, _openDataConfig8, _openDataConfig9;
|
|
594
610
|
return _regeneratorRuntime().wrap(function _callee9$(_context9) {
|
|
595
611
|
while (1) switch (_context9.prev = _context9.next) {
|
|
596
612
|
case 0:
|
|
@@ -648,10 +664,10 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
|
|
|
648
664
|
config: {
|
|
649
665
|
prefix: prefix,
|
|
650
666
|
deviceCode: deviceId,
|
|
651
|
-
|
|
652
|
-
padReceiptSequence: false,
|
|
667
|
+
padReceiptSequence: ((_openDataConfig7 = openDataConfig) === null || _openDataConfig7 === void 0 ? void 0 : _openDataConfig7['sale.pad_with_leading_zeros']) === true,
|
|
653
668
|
receiptSequenceLength: receiptSequenceLength,
|
|
654
|
-
|
|
669
|
+
receiptSequenceMax: this.normalizeShortNumberMaximum((_openDataConfig8 = openDataConfig) === null || _openDataConfig8 === void 0 ? void 0 : _openDataConfig8['sale.maximum_number']),
|
|
670
|
+
randomReceiptSequence: ((_openDataConfig9 = openDataConfig) === null || _openDataConfig9 === void 0 ? void 0 : _openDataConfig9['sale.short_number_random']) === true,
|
|
655
671
|
resetReceiptSequenceDaily: resetReceiptSequenceDaily,
|
|
656
672
|
receiptSequenceResetTime: operatingDayBoundary === null || operatingDayBoundary === void 0 ? void 0 : operatingDayBoundary.time,
|
|
657
673
|
receiptSequenceStart: receiptSequenceStart,
|
|
@@ -683,6 +699,19 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
|
|
|
683
699
|
if (!Number.isInteger(numeric) || numeric <= 0) return fallback;
|
|
684
700
|
return numeric;
|
|
685
701
|
}
|
|
702
|
+
}, {
|
|
703
|
+
key: "normalizeShortNumberMaximum",
|
|
704
|
+
value: function normalizeShortNumberMaximum(value) {
|
|
705
|
+
if (value === undefined || value === null || typeof value === 'string' && !value.trim()) return null;
|
|
706
|
+
if (typeof value !== 'number' && typeof value !== 'string') {
|
|
707
|
+
throw new Error('sale.maximum_number 必须是安全正整数或空值');
|
|
708
|
+
}
|
|
709
|
+
var numeric = Number(value);
|
|
710
|
+
if (!Number.isSafeInteger(numeric) || numeric <= 0) {
|
|
711
|
+
throw new Error('sale.maximum_number 必须是安全正整数或空值');
|
|
712
|
+
}
|
|
713
|
+
return numeric;
|
|
714
|
+
}
|
|
686
715
|
}, {
|
|
687
716
|
key: "normalizeIdPrefix",
|
|
688
717
|
value: function normalizeIdPrefix(value, fallback) {
|
|
@@ -74,6 +74,8 @@ export interface OpenDataConfig {
|
|
|
74
74
|
'sale.enable_item_rules'?: boolean;
|
|
75
75
|
'sale.enable_short_number'?: boolean;
|
|
76
76
|
'sale.short_number_digits'?: number;
|
|
77
|
+
'sale.maximum_number'?: number | string | null;
|
|
78
|
+
'sale.pad_with_leading_zeros'?: boolean | null;
|
|
77
79
|
'sale.short_number_random'?: boolean;
|
|
78
80
|
'sale.short_number_daily_reset'?: boolean;
|
|
79
81
|
'sale.short_number_start_number'?: number;
|
package/lib/server/index.js
CHANGED
|
@@ -17,6 +17,7 @@ var _resource = require("./modules/resource");
|
|
|
17
17
|
var _floorPlan = require("./modules/floor-plan");
|
|
18
18
|
var _types = require("./modules/floor-plan/types");
|
|
19
19
|
var _payment = require("./modules/payment");
|
|
20
|
+
var _form = require("./modules/form");
|
|
20
21
|
var _schedule2 = require("./utils/schedule");
|
|
21
22
|
var _time = require("./utils/time");
|
|
22
23
|
var _types2 = require("./modules/products/types");
|
|
@@ -183,6 +184,16 @@ class Server {
|
|
|
183
184
|
payMethods: []
|
|
184
185
|
}
|
|
185
186
|
},
|
|
187
|
+
form: {
|
|
188
|
+
name: 'form',
|
|
189
|
+
moduleClass: _form.FormModule,
|
|
190
|
+
moduleName: 'server_form',
|
|
191
|
+
version: '1.0.0',
|
|
192
|
+
defaultStore: {
|
|
193
|
+
list: [],
|
|
194
|
+
map: new Map()
|
|
195
|
+
}
|
|
196
|
+
},
|
|
186
197
|
resource: {
|
|
187
198
|
name: 'resource',
|
|
188
199
|
moduleClass: _resource.ResourceModule,
|
|
@@ -1349,7 +1360,7 @@ class Server {
|
|
|
1349
1360
|
data
|
|
1350
1361
|
}) => ({
|
|
1351
1362
|
code: 200,
|
|
1352
|
-
data: await this.order?.
|
|
1363
|
+
data: await this.order?.getLocalOrderForPaymentReadiness(data?.sale_id)
|
|
1353
1364
|
})
|
|
1354
1365
|
}, {
|
|
1355
1366
|
method: 'post',
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseModule } from '../../../modules/BaseModule';
|
|
2
|
+
import type { Module, ModuleOptions, PisellCore } from '../../../types';
|
|
3
|
+
/**
|
|
4
|
+
* 表单定义缓存。数据源负责 HTTP 与 Ably 订阅;本模块仅向 OS 消费方公开只读标题映射。
|
|
5
|
+
*/
|
|
6
|
+
export declare class FormModule extends BaseModule implements Module {
|
|
7
|
+
protected defaultName: string;
|
|
8
|
+
protected defaultVersion: string;
|
|
9
|
+
private store;
|
|
10
|
+
private dataSource;
|
|
11
|
+
private refreshTimer?;
|
|
12
|
+
initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
|
|
13
|
+
preload(): Promise<void>;
|
|
14
|
+
getTitleMap(): Record<string, Record<string, string> | string>;
|
|
15
|
+
private scheduleRefresh;
|
|
16
|
+
private refresh;
|
|
17
|
+
destroy(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export default FormModule;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.FormModule = void 0;
|
|
7
|
+
var _BaseModule = require("../../../modules/BaseModule");
|
|
8
|
+
var _types = require("./types");
|
|
9
|
+
const FORM_LIST_URL = '/shop/form/simple/list';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 表单定义缓存。数据源负责 HTTP 与 Ably 订阅;本模块仅向 OS 消费方公开只读标题映射。
|
|
13
|
+
*/
|
|
14
|
+
class FormModule extends _BaseModule.BaseModule {
|
|
15
|
+
defaultName = 'form';
|
|
16
|
+
defaultVersion = '1.0.0';
|
|
17
|
+
store;
|
|
18
|
+
dataSource;
|
|
19
|
+
refreshTimer;
|
|
20
|
+
async initialize(core, options) {
|
|
21
|
+
this.core = core;
|
|
22
|
+
const initialStore = options?.store;
|
|
23
|
+
this.store = {
|
|
24
|
+
list: Array.isArray(initialStore?.list) ? initialStore.list : [],
|
|
25
|
+
map: initialStore?.map instanceof Map ? initialStore.map : new Map()
|
|
26
|
+
};
|
|
27
|
+
const FormDataSource = this.core.serverOptions?.All_DATA_SOURCES?.FormDataSource;
|
|
28
|
+
this.dataSource = FormDataSource ? new FormDataSource() : undefined;
|
|
29
|
+
if (this.dataSource) {
|
|
30
|
+
await this.dataSource.run({
|
|
31
|
+
pubsub: {
|
|
32
|
+
callback: () => this.scheduleRefresh()
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async preload() {
|
|
38
|
+
await this.refresh();
|
|
39
|
+
}
|
|
40
|
+
getTitleMap() {
|
|
41
|
+
return this.store.list.reduce((result, item) => {
|
|
42
|
+
if (item.id !== undefined && item.id !== null && item.title) result[String(item.id)] = item.title;
|
|
43
|
+
return result;
|
|
44
|
+
}, {});
|
|
45
|
+
}
|
|
46
|
+
scheduleRefresh() {
|
|
47
|
+
if (this.refreshTimer) clearTimeout(this.refreshTimer);
|
|
48
|
+
this.refreshTimer = setTimeout(() => void this.refresh(), 300);
|
|
49
|
+
}
|
|
50
|
+
async refresh() {
|
|
51
|
+
try {
|
|
52
|
+
const response = this.dataSource ? await this.dataSource.run({
|
|
53
|
+
http: {
|
|
54
|
+
url: FORM_LIST_URL
|
|
55
|
+
}
|
|
56
|
+
}) : await this.core.getPlugin('request')?.get(FORM_LIST_URL);
|
|
57
|
+
const data = response?.data;
|
|
58
|
+
const list = Array.isArray(data) ? data : data?.list || data?.data || [];
|
|
59
|
+
if (!Array.isArray(list)) return;
|
|
60
|
+
this.store.list = list;
|
|
61
|
+
this.store.map = new Map(this.store.list.map(item => [String(item.id), item]));
|
|
62
|
+
await this.core.effects.emit(_types.FormHooks.onChanged, this.getTitleMap());
|
|
63
|
+
} catch {
|
|
64
|
+
// 接口尚未发布或临时失败时保留现有缓存,展示层会回退订单历史标题。
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async destroy() {
|
|
68
|
+
if (this.refreshTimer) clearTimeout(this.refreshTimer);
|
|
69
|
+
this.dataSource?.destroy?.();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.FormModule = FormModule;
|
|
73
|
+
var _default = exports.default = FormModule;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface FormDefinition {
|
|
2
|
+
id: string | number;
|
|
3
|
+
code?: string;
|
|
4
|
+
title?: Record<string, string> | string;
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
}
|
|
7
|
+
export interface FormState {
|
|
8
|
+
list: FormDefinition[];
|
|
9
|
+
map: Map<string, FormDefinition>;
|
|
10
|
+
}
|
|
11
|
+
export declare const FormHooks: {
|
|
12
|
+
readonly onChanged: "form:onChanged";
|
|
13
|
+
};
|
|
@@ -24,4 +24,7 @@ export { FloorPlanHooks } from './floor-plan/types';
|
|
|
24
24
|
export { ResourceModule, resourceModule } from './resource';
|
|
25
25
|
export type { ResourceState, ResourceData, ResourceId, ResourceBooking, ResourcePageQuery, ResourcePageResult, QueryOptions, ScheduleEventResource, } from './resource';
|
|
26
26
|
export { ResourceHooks } from './resource';
|
|
27
|
+
export { FormModule } from './form';
|
|
28
|
+
export type { FormDefinition, FormState } from './form/types';
|
|
29
|
+
export { FormHooks } from './form/types';
|
|
27
30
|
export type { RouteHandler, HttpMethod, RouteDefinition, Router, ModuleRegistryConfig, } from '../types';
|
|
@@ -15,6 +15,18 @@ Object.defineProperty(exports, "FloorPlanModule", {
|
|
|
15
15
|
return _floorPlan.FloorPlanModule;
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
|
+
Object.defineProperty(exports, "FormHooks", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _types6.FormHooks;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "FormModule", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _form.FormModule;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
18
30
|
Object.defineProperty(exports, "MenuHooks", {
|
|
19
31
|
enumerable: true,
|
|
20
32
|
get: function () {
|
|
@@ -105,4 +117,6 @@ var _types4 = require("./order/types");
|
|
|
105
117
|
var _payment = require("./payment");
|
|
106
118
|
var _floorPlan = require("./floor-plan");
|
|
107
119
|
var _types5 = require("./floor-plan/types");
|
|
108
|
-
var _resource = require("./resource");
|
|
120
|
+
var _resource = require("./resource");
|
|
121
|
+
var _form = require("./form");
|
|
122
|
+
var _types6 = require("./form/types");
|
|
@@ -105,6 +105,8 @@ export declare class OrderModule extends BaseModule implements Module {
|
|
|
105
105
|
getOrderByOrderId(orderId: OrderId): OrderData | undefined;
|
|
106
106
|
private buildLocalPaymentOrderLogContext;
|
|
107
107
|
getLocalOrderFromMemoryByLookup(lookup: OrderId): OrderData | null;
|
|
108
|
+
/** Read-only payment gate lookup; never hydrate the whole order list on a miss. */
|
|
109
|
+
getLocalOrderForPaymentReadiness(lookup: OrderId): Promise<OrderData | null>;
|
|
108
110
|
getLocalOrderByLookup(lookup: OrderId, options?: {
|
|
109
111
|
operationId?: string;
|
|
110
112
|
}): Promise<OrderData | null>;
|
|
@@ -638,6 +638,42 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
638
638
|
const memoryOrder = this.store.list.find(order => this.isOrderLookupMatch(order, key));
|
|
639
639
|
return memoryOrder || null;
|
|
640
640
|
}
|
|
641
|
+
|
|
642
|
+
/** Read-only payment gate lookup; never hydrate the whole order list on a miss. */
|
|
643
|
+
async getLocalOrderForPaymentReadiness(lookup) {
|
|
644
|
+
if (lookup === undefined || lookup === null || lookup === '') return null;
|
|
645
|
+
const memoryOrder = this.getLocalOrderFromMemoryByLookup(lookup);
|
|
646
|
+
if (memoryOrder) return memoryOrder;
|
|
647
|
+
if (typeof this.dbManager?.find !== 'function') {
|
|
648
|
+
return this.getLocalOrderByLookup(lookup);
|
|
649
|
+
}
|
|
650
|
+
const key = this.getIdKey(lookup);
|
|
651
|
+
const fields = ['order_id', 'external_sale_number', 'order_number', 'shop_order_number', 'shop_full_order_number'];
|
|
652
|
+
const candidates = [];
|
|
653
|
+
for (const column of fields) {
|
|
654
|
+
// Match getAll's storage-key ordering even when aliases collide across rows.
|
|
655
|
+
// Let query errors reach the payment gate rather than treating them as a miss.
|
|
656
|
+
const rows = await this.dbManager.find(INDEXDB_STORE_NAME, {
|
|
657
|
+
filters: [{
|
|
658
|
+
column,
|
|
659
|
+
op: '=',
|
|
660
|
+
value: key
|
|
661
|
+
}],
|
|
662
|
+
orderBy: [{
|
|
663
|
+
column: '__order_storage_key',
|
|
664
|
+
dir: 'asc'
|
|
665
|
+
}],
|
|
666
|
+
limit: 1
|
|
667
|
+
});
|
|
668
|
+
if (rows?.[0] && this.isOrderLookupMatch(rows[0], key)) candidates.push(rows[0]);
|
|
669
|
+
}
|
|
670
|
+
candidates.sort((left, right) => {
|
|
671
|
+
const leftKey = String(left.__order_storage_key ?? this.getOrderStorageKey(left));
|
|
672
|
+
const rightKey = String(right.__order_storage_key ?? this.getOrderStorageKey(right));
|
|
673
|
+
return leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0;
|
|
674
|
+
});
|
|
675
|
+
return candidates.length ? this.normalizeOrderForMemoryList(candidates[0], 'paymentReadiness.sqlite') : null;
|
|
676
|
+
}
|
|
641
677
|
async getLocalOrderByLookup(lookup, options = {}) {
|
|
642
678
|
const key = this.getIdKey(lookup);
|
|
643
679
|
const logContext = {
|
|
@@ -328,7 +328,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
328
328
|
date: string;
|
|
329
329
|
status: string;
|
|
330
330
|
week: string;
|
|
331
|
-
weekNum: 0 |
|
|
331
|
+
weekNum: 0 | 1 | 2 | 6 | 3 | 4 | 5;
|
|
332
332
|
}[]>;
|
|
333
333
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
334
334
|
private getScheduleDataByIds;
|
|
@@ -42,6 +42,10 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
42
42
|
*/
|
|
43
43
|
protected getRegisteredModuleNames(): readonly string[];
|
|
44
44
|
protected getSubmitOrderSalesChannel(): string;
|
|
45
|
+
/** 供销售展示层按 booking.resources[].form_id 读取当前多语言表单标题。 */
|
|
46
|
+
getFormTitleMap(): Record<string, Record<string, string> | string>;
|
|
47
|
+
/** 表单定义由 Ably 更新后通知展示层刷新,不改动订单里的历史 metadata。 */
|
|
48
|
+
onFormTitlesChanged(callback: (titles: Record<string, Record<string, string> | string>) => void): () => void;
|
|
45
49
|
/**
|
|
46
50
|
* 业务侧子模块工厂:BookingTicket 自带的 createBookingTicketModule 优先匹配;
|
|
47
51
|
* 未识别的模块名(如 BookingByStep 公共类型)回退到父类工厂。
|
|
@@ -67,6 +71,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
67
71
|
private getShortNumberOrDeviceId;
|
|
68
72
|
private configureIdGeneratorFromOpenData;
|
|
69
73
|
private normalizePositiveInteger;
|
|
74
|
+
private normalizeShortNumberMaximum;
|
|
70
75
|
private normalizeIdPrefix;
|
|
71
76
|
/**
|
|
72
77
|
* 加载销售详情,并在父类基础上把 customer 信息装配到 CustomerModule。
|
|
@@ -39,6 +39,7 @@ var _orderLineDisplay = require("../../modules/BookingContext/utils/orderLineDis
|
|
|
39
39
|
var _bookingStatus = require("./utils/bookingStatus");
|
|
40
40
|
var _resolveBestAddTimePlan = require("./utils/resolveBestAddTimePlan");
|
|
41
41
|
var _utils = require("../../modules/Order/utils");
|
|
42
|
+
var _types2 = require("../../server/modules/form/types");
|
|
42
43
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
43
44
|
const OPEN_DATA_SECTION_CODES = ['sale', 'reservation', 'fulfillment', 'menu', 'workflow', 'documents'];
|
|
44
45
|
const OPEN_DATA_CACHE_TTL = 5 * 60 * 1000;
|
|
@@ -179,6 +180,16 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
179
180
|
return !channel || channel === 'system' ? 'pos' : channel;
|
|
180
181
|
}
|
|
181
182
|
|
|
183
|
+
/** 供销售展示层按 booking.resources[].form_id 读取当前多语言表单标题。 */
|
|
184
|
+
getFormTitleMap() {
|
|
185
|
+
return this.core?.server?.form?.getTitleMap?.() || {};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** 表单定义由 Ably 更新后通知展示层刷新,不改动订单里的历史 metadata。 */
|
|
189
|
+
onFormTitlesChanged(callback) {
|
|
190
|
+
return this.core.effects.on(_types2.FormHooks.onChanged, callback);
|
|
191
|
+
}
|
|
192
|
+
|
|
182
193
|
/**
|
|
183
194
|
* 业务侧子模块工厂:BookingTicket 自带的 createBookingTicketModule 优先匹配;
|
|
184
195
|
* 未识别的模块名(如 BookingByStep 公共类型)回退到父类工厂。
|
|
@@ -367,9 +378,9 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
367
378
|
config: {
|
|
368
379
|
prefix,
|
|
369
380
|
deviceCode: deviceId,
|
|
370
|
-
|
|
371
|
-
padReceiptSequence: false,
|
|
381
|
+
padReceiptSequence: openDataConfig?.['sale.pad_with_leading_zeros'] === true,
|
|
372
382
|
receiptSequenceLength,
|
|
383
|
+
receiptSequenceMax: this.normalizeShortNumberMaximum(openDataConfig?.['sale.maximum_number']),
|
|
373
384
|
randomReceiptSequence: openDataConfig?.['sale.short_number_random'] === true,
|
|
374
385
|
resetReceiptSequenceDaily,
|
|
375
386
|
receiptSequenceResetTime: operatingDayBoundary?.time,
|
|
@@ -386,6 +397,17 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
386
397
|
if (!Number.isInteger(numeric) || numeric <= 0) return fallback;
|
|
387
398
|
return numeric;
|
|
388
399
|
}
|
|
400
|
+
normalizeShortNumberMaximum(value) {
|
|
401
|
+
if (value === undefined || value === null || typeof value === 'string' && !value.trim()) return null;
|
|
402
|
+
if (typeof value !== 'number' && typeof value !== 'string') {
|
|
403
|
+
throw new Error('sale.maximum_number 必须是安全正整数或空值');
|
|
404
|
+
}
|
|
405
|
+
const numeric = Number(value);
|
|
406
|
+
if (!Number.isSafeInteger(numeric) || numeric <= 0) {
|
|
407
|
+
throw new Error('sale.maximum_number 必须是安全正整数或空值');
|
|
408
|
+
}
|
|
409
|
+
return numeric;
|
|
410
|
+
}
|
|
389
411
|
normalizeIdPrefix(value, fallback) {
|
|
390
412
|
if (value === undefined || value === null) return fallback;
|
|
391
413
|
const normalized = String(value).trim().toUpperCase();
|