@pisell/pisellos 2.2.291 → 2.2.293
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/core/index.d.ts +7 -0
- package/dist/core/index.js +108 -65
- package/dist/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
- package/dist/model/strategy/adapter/itemRule/adapter.js +135 -35
- package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
- package/dist/model/strategy/adapter/itemRule/evaluator.js +25 -1
- package/dist/model/strategy/adapter/itemRule/type.d.ts +44 -0
- package/dist/model/strategy/adapter/itemRule/type.js +19 -1
- package/dist/model/strategy/adapter/promotion/index.js +0 -9
- package/dist/modules/BookingContext/index.d.ts +3 -0
- package/dist/modules/BookingContext/index.js +42 -13
- package/dist/modules/BookingContext/types.d.ts +4 -4
- package/dist/modules/BookingContext/types.js +3 -3
- package/dist/modules/OpenData/types.d.ts +1 -0
- package/dist/modules/Order/index.d.ts +18 -3
- package/dist/modules/Order/index.js +885 -485
- package/dist/modules/Order/salesNotes.d.ts +31 -0
- package/dist/modules/Order/salesNotes.js +492 -0
- package/dist/modules/Order/types.d.ts +93 -5
- package/dist/modules/Order/types.js +5 -0
- package/dist/modules/Order/utils.d.ts +12 -0
- package/dist/modules/Order/utils.js +96 -31
- package/dist/modules/Product/types.d.ts +2 -0
- package/dist/modules/ProductList/clientDataVariants.d.ts +50 -0
- package/dist/modules/ProductList/clientDataVariants.js +216 -0
- package/dist/modules/ProductList/index.d.ts +18 -3
- package/dist/modules/ProductList/index.js +220 -38
- package/dist/modules/ProductList/types.d.ts +10 -0
- package/dist/modules/Quotation/index.d.ts +22 -0
- package/dist/modules/Quotation/index.js +293 -28
- package/dist/modules/ResourcePlanner/index.d.ts +0 -22
- package/dist/modules/ResourcePlanner/index.js +1 -180
- package/dist/modules/ResourcePlanner/localClock.d.ts +33 -0
- package/dist/modules/ResourcePlanner/localClock.js +183 -0
- package/dist/modules/ResourcePlanner/planner.d.ts +5 -14
- package/dist/modules/ResourcePlanner/planner.js +2111 -958
- package/dist/modules/ResourcePlanner/types.d.ts +359 -187
- package/dist/modules/ResourcePlanner/types.js +33 -1
- package/dist/plugins/request.d.ts +1 -0
- package/dist/server/index.d.ts +17 -2
- package/dist/server/index.js +1134 -932
- package/dist/server/modules/floor-plan/index.d.ts +4 -0
- package/dist/server/modules/floor-plan/index.js +240 -98
- package/dist/server/modules/menu/index.js +48 -23
- package/dist/server/modules/order/index.d.ts +17 -7
- package/dist/server/modules/order/index.js +419 -207
- package/dist/server/modules/products/index.d.ts +10 -4
- package/dist/server/modules/products/index.js +177 -84
- package/dist/server/modules/resource/index.js +21 -13
- package/dist/server/utils/product.d.ts +1 -1
- package/dist/server/utils/product.js +186 -22
- package/dist/server/utils/small-ticket.d.ts +9 -1
- package/dist/server/utils/small-ticket.js +131 -84
- package/dist/solution/BaseSales/index.d.ts +26 -3
- package/dist/solution/BaseSales/index.js +1384 -905
- package/dist/solution/BaseSales/types.d.ts +2 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +3 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +10 -3
- package/dist/solution/BaseSales/utils.js +6 -3
- package/dist/solution/BookingByStep/index.d.ts +4 -4
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.js +4 -2
- package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +2 -1
- package/dist/solution/BookingTicket/utils/addProductDecision.js +6 -3
- package/dist/solution/BookingTicket/utils/orderCustomer.js +3 -2
- package/dist/solution/RegisterAndLogin/config.d.ts +9 -3
- package/dist/solution/RegisterAndLogin/config.js +95 -40
- package/dist/solution/RegisterAndLogin/index.js +4 -1
- package/dist/solution/ScanOrder/index.d.ts +1 -0
- package/dist/solution/ScanOrder/index.js +31 -27
- package/dist/solution/ScanOrder/types.d.ts +2 -0
- package/dist/solution/ScanOrder/utils.d.ts +1 -0
- package/dist/solution/ScanOrder/utils.js +8 -3
- package/dist/solution/UnifiedBookingSales/index.d.ts +128 -74
- package/dist/solution/UnifiedBookingSales/index.js +3877 -963
- package/dist/solution/UnifiedBookingSales/remoteOccupancyCache.d.ts +49 -0
- package/dist/solution/UnifiedBookingSales/remoteOccupancyCache.js +430 -0
- package/dist/solution/UnifiedBookingSales/types.d.ts +161 -77
- package/dist/solution/UnifiedBookingSales/types.js +4 -9
- package/dist/solution/VenueBooking/index.d.ts +3 -0
- package/dist/solution/VenueBooking/index.js +549 -497
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
- package/dist/solution/VenueBooking/utils/dateSummary.js +3 -1
- package/dist/solution/VenueBooking/utils/slotMerge.d.ts +2 -0
- package/dist/solution/VenueBooking/utils/slotMerge.js +3 -1
- package/dist/utils/platform.d.ts +8 -0
- package/dist/utils/platform.js +15 -0
- package/lib/core/index.d.ts +7 -0
- package/lib/core/index.js +20 -2
- package/lib/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
- package/lib/model/strategy/adapter/itemRule/adapter.js +73 -4
- package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
- package/lib/model/strategy/adapter/itemRule/evaluator.js +23 -1
- package/lib/model/strategy/adapter/itemRule/type.d.ts +44 -0
- package/lib/model/strategy/adapter/itemRule/type.js +19 -1
- package/lib/modules/BookingContext/index.d.ts +3 -0
- package/lib/modules/BookingContext/index.js +35 -8
- package/lib/modules/BookingContext/types.d.ts +4 -4
- package/lib/modules/BookingContext/types.js +3 -3
- package/lib/modules/OpenData/types.d.ts +1 -0
- package/lib/modules/Order/index.d.ts +18 -3
- package/lib/modules/Order/index.js +325 -28
- package/lib/modules/Order/salesNotes.d.ts +31 -0
- package/lib/modules/Order/salesNotes.js +382 -0
- package/lib/modules/Order/types.d.ts +93 -5
- package/lib/modules/Order/types.js +4 -0
- package/lib/modules/Order/utils.d.ts +12 -0
- package/lib/modules/Order/utils.js +85 -16
- package/lib/modules/Product/types.d.ts +2 -0
- package/lib/modules/ProductList/clientDataVariants.d.ts +50 -0
- package/lib/modules/ProductList/clientDataVariants.js +204 -0
- package/lib/modules/ProductList/index.d.ts +18 -3
- package/lib/modules/ProductList/index.js +137 -8
- package/lib/modules/ProductList/types.d.ts +10 -0
- package/lib/modules/Quotation/index.d.ts +22 -0
- package/lib/modules/Quotation/index.js +158 -11
- package/lib/modules/ResourcePlanner/index.d.ts +0 -22
- package/lib/modules/ResourcePlanner/index.js +9 -129
- package/lib/modules/ResourcePlanner/localClock.d.ts +33 -0
- package/lib/modules/ResourcePlanner/localClock.js +205 -0
- package/lib/modules/ResourcePlanner/planner.d.ts +5 -14
- package/lib/modules/ResourcePlanner/planner.js +1807 -783
- package/lib/modules/ResourcePlanner/types.d.ts +359 -187
- package/lib/modules/ResourcePlanner/types.js +13 -1
- package/lib/plugins/request.d.ts +1 -0
- package/lib/server/index.d.ts +17 -2
- package/lib/server/index.js +149 -21
- package/lib/server/modules/floor-plan/index.d.ts +4 -0
- package/lib/server/modules/floor-plan/index.js +60 -7
- package/lib/server/modules/menu/index.js +26 -4
- package/lib/server/modules/order/index.d.ts +17 -7
- package/lib/server/modules/order/index.js +194 -57
- package/lib/server/modules/products/index.d.ts +10 -4
- package/lib/server/modules/products/index.js +93 -23
- package/lib/server/modules/resource/index.js +12 -2
- package/lib/server/utils/product.d.ts +1 -1
- package/lib/server/utils/product.js +163 -3
- package/lib/server/utils/small-ticket.d.ts +9 -1
- package/lib/server/utils/small-ticket.js +123 -79
- package/lib/solution/BaseSales/index.d.ts +26 -3
- package/lib/solution/BaseSales/index.js +396 -70
- package/lib/solution/BaseSales/types.d.ts +2 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +3 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +9 -2
- package/lib/solution/BaseSales/utils.js +3 -0
- package/lib/solution/BookingByStep/index.d.ts +4 -4
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.js +2 -1
- package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +2 -1
- package/lib/solution/BookingTicket/utils/addProductDecision.js +5 -2
- package/lib/solution/BookingTicket/utils/orderCustomer.js +2 -1
- package/lib/solution/RegisterAndLogin/config.d.ts +9 -3
- package/lib/solution/RegisterAndLogin/config.js +49 -8
- package/lib/solution/RegisterAndLogin/index.js +4 -1
- package/lib/solution/ScanOrder/index.d.ts +1 -0
- package/lib/solution/ScanOrder/index.js +5 -1
- package/lib/solution/ScanOrder/types.d.ts +2 -0
- package/lib/solution/ScanOrder/utils.d.ts +1 -0
- package/lib/solution/ScanOrder/utils.js +4 -0
- package/lib/solution/UnifiedBookingSales/index.d.ts +128 -74
- package/lib/solution/UnifiedBookingSales/index.js +2592 -424
- package/lib/solution/UnifiedBookingSales/remoteOccupancyCache.d.ts +49 -0
- package/lib/solution/UnifiedBookingSales/remoteOccupancyCache.js +316 -0
- package/lib/solution/UnifiedBookingSales/types.d.ts +161 -77
- package/lib/solution/UnifiedBookingSales/types.js +4 -6
- package/lib/solution/VenueBooking/index.d.ts +3 -0
- package/lib/solution/VenueBooking/index.js +33 -9
- package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
- package/lib/solution/VenueBooking/utils/dateSummary.js +3 -1
- package/lib/solution/VenueBooking/utils/slotMerge.d.ts +2 -0
- package/lib/solution/VenueBooking/utils/slotMerge.js +3 -1
- package/lib/utils/platform.d.ts +8 -0
- package/lib/utils/platform.js +22 -0
- package/package.json +1 -1
|
@@ -7,5 +7,6 @@ export declare function buildDateRangeSummary(params: {
|
|
|
7
7
|
rawResources: VenueResourceRawData[];
|
|
8
8
|
resourceProductMap: Map<number | string, ResourceProductMapping[]>;
|
|
9
9
|
quotationModule?: QuotationModule;
|
|
10
|
+
channel?: string;
|
|
10
11
|
resolveConfig?: (date: string) => VenueBookingSlotConfig;
|
|
11
12
|
}): VenueDateSummaryItem[];
|
|
@@ -14,6 +14,7 @@ export function buildDateRangeSummary(params) {
|
|
|
14
14
|
rawResources = params.rawResources,
|
|
15
15
|
resourceProductMap = params.resourceProductMap,
|
|
16
16
|
quotationModule = params.quotationModule,
|
|
17
|
+
channel = params.channel,
|
|
17
18
|
resolveConfig = params.resolveConfig;
|
|
18
19
|
var result = [];
|
|
19
20
|
var productIds = quotationModule ? _toConsumableArray(new Set(_toConsumableArray(resourceProductMap.values()).flat().map(function (m) {
|
|
@@ -32,7 +33,8 @@ export function buildDateRangeSummary(params) {
|
|
|
32
33
|
});
|
|
33
34
|
quotationPriceMap = quotationModule.buildProductPriceMap({
|
|
34
35
|
productIds: productIds,
|
|
35
|
-
timePoints: timePoints
|
|
36
|
+
timePoints: timePoints,
|
|
37
|
+
channel: channel
|
|
36
38
|
});
|
|
37
39
|
}
|
|
38
40
|
var grid = buildTimeSlotGrid({
|
|
@@ -5,10 +5,12 @@ export declare function mergeConsecutiveSlots(slots: VenueSlotSelection[]): Merg
|
|
|
5
5
|
export declare function buildPriceBreakdown(params: {
|
|
6
6
|
group: MergedSlotGroup;
|
|
7
7
|
productId: number;
|
|
8
|
+
channel?: string;
|
|
8
9
|
quotation?: {
|
|
9
10
|
getQuotationShelfId: (p: {
|
|
10
11
|
productId: number;
|
|
11
12
|
datetime: string;
|
|
13
|
+
channel?: string;
|
|
12
14
|
}) => number;
|
|
13
15
|
};
|
|
14
16
|
}): PriceBreakdownEntry[];
|
|
@@ -53,6 +53,7 @@ export function mergeConsecutiveSlots(slots) {
|
|
|
53
53
|
export function buildPriceBreakdown(params) {
|
|
54
54
|
var group = params.group,
|
|
55
55
|
productId = params.productId,
|
|
56
|
+
channel = params.channel,
|
|
56
57
|
quotation = params.quotation;
|
|
57
58
|
if (!group.slots.length) return [];
|
|
58
59
|
var entries = [];
|
|
@@ -64,7 +65,8 @@ export function buildPriceBreakdown(params) {
|
|
|
64
65
|
var unitPrice = Number(slot.price || '0');
|
|
65
66
|
var shelfId = quotation ? quotation.getQuotationShelfId({
|
|
66
67
|
productId: productId,
|
|
67
|
-
datetime: slot.startTime
|
|
68
|
+
datetime: slot.startTime,
|
|
69
|
+
channel: channel
|
|
68
70
|
}) : 0;
|
|
69
71
|
var startHm = dayjs(slot.startTime, 'YYYY-MM-DD HH:mm').format('YYYY-MM-DD HH:mm');
|
|
70
72
|
var endHm = dayjs(slot.endTime, 'YYYY-MM-DD HH:mm').format('YYYY-MM-DD HH:mm');
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize the runtime platform passed through solution/module otherParams.
|
|
3
|
+
*/
|
|
4
|
+
export declare function normalizeRuntimePlatform(platform: unknown): string;
|
|
5
|
+
/**
|
|
6
|
+
* PC and H5 are authenticated-customer clients rather than staff terminals.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isCustomerUserPlatform(platform: unknown): boolean;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
var CUSTOMER_USER_PLATFORMS = new Set(['pc', 'h5']);
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Normalize the runtime platform passed through solution/module otherParams.
|
|
5
|
+
*/
|
|
6
|
+
export function normalizeRuntimePlatform(platform) {
|
|
7
|
+
return String(platform !== null && platform !== void 0 ? platform : '').trim().toLowerCase();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* PC and H5 are authenticated-customer clients rather than staff terminals.
|
|
12
|
+
*/
|
|
13
|
+
export function isCustomerUserPlatform(platform) {
|
|
14
|
+
return CUSTOMER_USER_PLATFORMS.has(normalizeRuntimePlatform(platform));
|
|
15
|
+
}
|
package/lib/core/index.d.ts
CHANGED
|
@@ -12,8 +12,15 @@ declare class PisellOSCore implements PisellCore {
|
|
|
12
12
|
context: BusinessContext;
|
|
13
13
|
server: any;
|
|
14
14
|
serverOptions?: ServerOptions;
|
|
15
|
+
private serverModulePromise?;
|
|
15
16
|
constructor(options?: PisellOSOptions);
|
|
16
17
|
private initialize;
|
|
18
|
+
/**
|
|
19
|
+
* 仅预加载 Server 模块代码,不创建实例、不注册模块、不请求业务数据。
|
|
20
|
+
* 导入失败会清空 Promise,正式 initializeServer 时仍可重新尝试。
|
|
21
|
+
*/
|
|
22
|
+
preloadServerModule(): Promise<void>;
|
|
23
|
+
private loadServerModule;
|
|
17
24
|
/**
|
|
18
25
|
* 初始化 Server(公开方法,需要外部显式调用并等待)
|
|
19
26
|
* Server 配置从构造函数传入的 options.server 中获取
|
package/lib/core/index.js
CHANGED
|
@@ -20,7 +20,7 @@ class PisellOSCore {
|
|
|
20
20
|
context = {};
|
|
21
21
|
server; // Server 实例
|
|
22
22
|
serverOptions; // 保存 Server 配置
|
|
23
|
-
|
|
23
|
+
serverModulePromise;
|
|
24
24
|
constructor(options) {
|
|
25
25
|
this.debug = options?.debug || false;
|
|
26
26
|
this.context = options?.context || {};
|
|
@@ -45,6 +45,24 @@ class PisellOSCore {
|
|
|
45
45
|
this.log('[PisellOS] 核心初始化完成');
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* 仅预加载 Server 模块代码,不创建实例、不注册模块、不请求业务数据。
|
|
50
|
+
* 导入失败会清空 Promise,正式 initializeServer 时仍可重新尝试。
|
|
51
|
+
*/
|
|
52
|
+
async preloadServerModule() {
|
|
53
|
+
if (this.server || !this.serverOptions) return;
|
|
54
|
+
await this.loadServerModule();
|
|
55
|
+
}
|
|
56
|
+
loadServerModule() {
|
|
57
|
+
if (!this.serverModulePromise) {
|
|
58
|
+
this.serverModulePromise = Promise.resolve().then(() => _interopRequireWildcard(require("../server"))).catch(error => {
|
|
59
|
+
this.serverModulePromise = undefined;
|
|
60
|
+
throw error;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return this.serverModulePromise;
|
|
64
|
+
}
|
|
65
|
+
|
|
48
66
|
/**
|
|
49
67
|
* 初始化 Server(公开方法,需要外部显式调用并等待)
|
|
50
68
|
* Server 配置从构造函数传入的 options.server 中获取
|
|
@@ -63,7 +81,7 @@ class PisellOSCore {
|
|
|
63
81
|
}
|
|
64
82
|
try {
|
|
65
83
|
// 动态导入 Server 类以避免循环依赖
|
|
66
|
-
const ServerModule = await
|
|
84
|
+
const ServerModule = await this.loadServerModule();
|
|
67
85
|
const Server = ServerModule.default;
|
|
68
86
|
|
|
69
87
|
// 创建 Server 实例
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EvaluationResult, RuntimeContext, ActionEffect } from '../../type';
|
|
2
2
|
import type { BusinessAdapter } from '../type';
|
|
3
|
-
import { type ItemRuleBusinessData, type QuantityCheckResult, type PrefillItemResult, type QuantityLimitResult } from './type';
|
|
3
|
+
import { type ItemRuleBusinessData, type QuantityCheckResult, type PrefillItemResult, type QuantityLimitResult, type AllergyRequirement } from './type';
|
|
4
4
|
/**
|
|
5
5
|
* ItemRule 适配器
|
|
6
6
|
*
|
|
@@ -14,7 +14,10 @@ export declare class ItemRuleAdapter implements BusinessAdapter {
|
|
|
14
14
|
transformResult(result: EvaluationResult, businessData?: ItemRuleBusinessData): {
|
|
15
15
|
quantityChecks: QuantityCheckResult[];
|
|
16
16
|
prefillItems: PrefillItemResult[];
|
|
17
|
+
allergyRequirements: AllergyRequirement[];
|
|
17
18
|
};
|
|
19
|
+
private processAllergyCheck;
|
|
20
|
+
private normalizeAllergyDataSourceItems;
|
|
18
21
|
formatConfig(result: EvaluationResult, businessData?: ItemRuleBusinessData): {
|
|
19
22
|
result: EvaluationResult;
|
|
20
23
|
businessData?: ItemRuleBusinessData;
|
|
@@ -19,14 +19,17 @@ class ItemRuleAdapter {
|
|
|
19
19
|
pax,
|
|
20
20
|
cartItems,
|
|
21
21
|
serviceType,
|
|
22
|
+
channel,
|
|
22
23
|
submissionIndex,
|
|
23
24
|
custom
|
|
24
25
|
} = businessData;
|
|
26
|
+
const resolvedChannel = String(channel ?? custom?.channel ?? '').trim();
|
|
25
27
|
return {
|
|
26
28
|
entities: {
|
|
27
29
|
cartItems,
|
|
28
30
|
historicalItems: businessData.historicalItems || [],
|
|
29
|
-
pax
|
|
31
|
+
pax,
|
|
32
|
+
currentProduct: businessData.currentProduct
|
|
30
33
|
},
|
|
31
34
|
attributes: {
|
|
32
35
|
serviceType: serviceType || '',
|
|
@@ -36,7 +39,8 @@ class ItemRuleAdapter {
|
|
|
36
39
|
submissionIndex: submissionIndex ?? 0,
|
|
37
40
|
cartItemCount: cartItems.length,
|
|
38
41
|
cartTotalQuantity: cartItems.reduce((sum, item) => sum + item.quantity, 0),
|
|
39
|
-
...custom
|
|
42
|
+
...custom,
|
|
43
|
+
channel: resolvedChannel
|
|
40
44
|
},
|
|
41
45
|
metadata: {
|
|
42
46
|
timestamp: Date.now()
|
|
@@ -46,10 +50,12 @@ class ItemRuleAdapter {
|
|
|
46
50
|
transformResult(result, businessData) {
|
|
47
51
|
const quantityChecks = [];
|
|
48
52
|
const prefillItems = [];
|
|
53
|
+
const allergyRequirements = [];
|
|
49
54
|
if (!result.applicable || !businessData) {
|
|
50
55
|
return {
|
|
51
56
|
quantityChecks,
|
|
52
|
-
prefillItems
|
|
57
|
+
prefillItems,
|
|
58
|
+
allergyRequirements
|
|
53
59
|
};
|
|
54
60
|
}
|
|
55
61
|
for (const action of result.matchedActions) {
|
|
@@ -61,13 +67,76 @@ class ItemRuleAdapter {
|
|
|
61
67
|
} else if (action.type === _type.ITEM_RULE_ACTION_TYPES.PREFILL_CART) {
|
|
62
68
|
const items = this.processPrefillCart(action, businessData);
|
|
63
69
|
prefillItems.push(...items);
|
|
70
|
+
} else if (action.type === _type.ITEM_RULE_ACTION_TYPES.ALLERGY_CHECK) {
|
|
71
|
+
const requirement = this.processAllergyCheck(action, result, businessData);
|
|
72
|
+
if (requirement) allergyRequirements.push(requirement);
|
|
64
73
|
}
|
|
65
74
|
}
|
|
66
75
|
return {
|
|
67
76
|
quantityChecks,
|
|
68
|
-
prefillItems
|
|
77
|
+
prefillItems,
|
|
78
|
+
allergyRequirements
|
|
69
79
|
};
|
|
70
80
|
}
|
|
81
|
+
|
|
82
|
+
// ============================================
|
|
83
|
+
// Allergy Check 处理
|
|
84
|
+
// ============================================
|
|
85
|
+
|
|
86
|
+
processAllergyCheck(action, result, businessData) {
|
|
87
|
+
const config = action.config;
|
|
88
|
+
const currentProduct = businessData.currentProduct;
|
|
89
|
+
if (!config || config.targetType !== 'product' || config.promptScope !== 'once_per_order_product' || !Array.isArray(config.targets) || !currentProduct) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
const currentProductId = Number(currentProduct.product_id);
|
|
93
|
+
const currentVariantId = Number(currentProduct.product_variant_id ?? 0);
|
|
94
|
+
if (!Number.isFinite(currentProductId) || currentProductId <= 0) return null;
|
|
95
|
+
const productTargets = config.targets.filter(item => Number(item.product_id) === currentProductId);
|
|
96
|
+
const target = productTargets.find(item => currentVariantId > 0 && Number(item.product_variant_id ?? 0) === currentVariantId) ?? productTargets.find(item => Number(item.product_variant_id ?? 0) <= 0);
|
|
97
|
+
if (!target || target.dataSource?.type !== 'inline') return null;
|
|
98
|
+
const items = this.normalizeAllergyDataSourceItems(target.dataSource.items);
|
|
99
|
+
if (!items.length) return null;
|
|
100
|
+
return {
|
|
101
|
+
strategyId: result.config.metadata.id,
|
|
102
|
+
ruleId: action.id,
|
|
103
|
+
priority: action.priority ?? 0,
|
|
104
|
+
targetType: 'product',
|
|
105
|
+
product_id: currentProductId,
|
|
106
|
+
...(Number(target.product_variant_id ?? 0) > 0 ? {
|
|
107
|
+
product_variant_id: Number(target.product_variant_id)
|
|
108
|
+
} : {}),
|
|
109
|
+
dataSource: {
|
|
110
|
+
type: 'inline',
|
|
111
|
+
items
|
|
112
|
+
},
|
|
113
|
+
promptScope: config.promptScope,
|
|
114
|
+
allowNote: config.allowNote === true
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
normalizeAllergyDataSourceItems(items) {
|
|
118
|
+
if (!Array.isArray(items)) return [];
|
|
119
|
+
const uniqueIds = new Set();
|
|
120
|
+
const normalized = [];
|
|
121
|
+
for (const item of items) {
|
|
122
|
+
const id = String(item?.id ?? '').trim();
|
|
123
|
+
const rawLabel = item?.label;
|
|
124
|
+
const label = typeof rawLabel === 'string' ? rawLabel.trim() : Object.entries(rawLabel || {}).reduce((labels, [locale, value]) => {
|
|
125
|
+
if (typeof value === 'string' && value.trim().length > 0) {
|
|
126
|
+
labels[locale] = value.trim();
|
|
127
|
+
}
|
|
128
|
+
return labels;
|
|
129
|
+
}, {});
|
|
130
|
+
const hasLabel = typeof label === 'string' ? label.length > 0 : Object.keys(label).length > 0;
|
|
131
|
+
if (!id || !hasLabel || uniqueIds.has(id)) continue;
|
|
132
|
+
uniqueIds.add(id);
|
|
133
|
+
normalized.push({
|
|
134
|
+
id,
|
|
135
|
+
label
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return normalized;
|
|
139
|
+
}
|
|
71
140
|
formatConfig(result, businessData) {
|
|
72
141
|
return {
|
|
73
142
|
result,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StrategyConfig } from '../../type';
|
|
2
|
-
import { type ItemRuleBusinessData, type ItemRuleEvaluationResult, type QuantityCheckResult, type QuantityLimitResult, type PrefillItemResult } from './type';
|
|
2
|
+
import { type ItemRuleBusinessData, type ItemRuleEvaluationResult, type QuantityCheckResult, type QuantityLimitResult, type PrefillItemResult, type AllergyRequirement } from './type';
|
|
3
3
|
/**
|
|
4
4
|
* ItemRule 评估器
|
|
5
5
|
*
|
|
@@ -21,6 +21,13 @@ export declare class ItemRuleEvaluator {
|
|
|
21
21
|
* 完整评估:数量校验 + 预填购物车
|
|
22
22
|
*/
|
|
23
23
|
evaluate(businessData: ItemRuleBusinessData): ItemRuleEvaluationResult;
|
|
24
|
+
/**
|
|
25
|
+
* 获取当前商品优先级最高的过敏门禁要求。
|
|
26
|
+
*
|
|
27
|
+
* 不同商品或不同 Action 的数据源不会合并;相同优先级按
|
|
28
|
+
* strategyId + ruleId 稳定排序,保证多次评估结果一致。
|
|
29
|
+
*/
|
|
30
|
+
getAllergyRequirement(businessData: ItemRuleBusinessData): AllergyRequirement | null;
|
|
24
31
|
/**
|
|
25
32
|
* 获取当前配置中各商品的数量限制
|
|
26
33
|
*
|
|
@@ -43,6 +43,7 @@ class ItemRuleEvaluator {
|
|
|
43
43
|
const configs = businessData.strategyConfigs ? businessData.strategyConfigs.filter(c => c.metadata.type === 'item_rule') : this.strategyConfigs;
|
|
44
44
|
const allQuantityChecks = [];
|
|
45
45
|
const allPrefillItems = [];
|
|
46
|
+
const allAllergyRequirements = [];
|
|
46
47
|
const rawResults = [];
|
|
47
48
|
const context = this.adapter.prepareContext(businessData);
|
|
48
49
|
for (const config of configs) {
|
|
@@ -50,21 +51,42 @@ class ItemRuleEvaluator {
|
|
|
50
51
|
rawResults.push(evalResult);
|
|
51
52
|
const {
|
|
52
53
|
quantityChecks,
|
|
53
|
-
prefillItems
|
|
54
|
+
prefillItems,
|
|
55
|
+
allergyRequirements
|
|
54
56
|
} = this.adapter.transformResult(evalResult, businessData);
|
|
55
57
|
allQuantityChecks.push(...quantityChecks);
|
|
56
58
|
allPrefillItems.push(...prefillItems);
|
|
59
|
+
allAllergyRequirements.push(...allergyRequirements);
|
|
57
60
|
}
|
|
58
61
|
const failedChecks = allQuantityChecks.filter(c => !c.passed);
|
|
59
62
|
return {
|
|
60
63
|
quantityChecks: allQuantityChecks,
|
|
61
64
|
prefillItems: allPrefillItems,
|
|
65
|
+
allergyRequirements: allAllergyRequirements,
|
|
62
66
|
allPassed: failedChecks.length === 0,
|
|
63
67
|
failedChecks,
|
|
64
68
|
rawResults
|
|
65
69
|
};
|
|
66
70
|
}
|
|
67
71
|
|
|
72
|
+
/**
|
|
73
|
+
* 获取当前商品优先级最高的过敏门禁要求。
|
|
74
|
+
*
|
|
75
|
+
* 不同商品或不同 Action 的数据源不会合并;相同优先级按
|
|
76
|
+
* strategyId + ruleId 稳定排序,保证多次评估结果一致。
|
|
77
|
+
*/
|
|
78
|
+
getAllergyRequirement(businessData) {
|
|
79
|
+
const requirements = this.evaluate(businessData).allergyRequirements;
|
|
80
|
+
if (!requirements.length) return null;
|
|
81
|
+
return [...requirements].sort((left, right) => {
|
|
82
|
+
const priorityDiff = right.priority - left.priority;
|
|
83
|
+
if (priorityDiff !== 0) return priorityDiff;
|
|
84
|
+
const strategyDiff = left.strategyId.localeCompare(right.strategyId);
|
|
85
|
+
if (strategyDiff !== 0) return strategyDiff;
|
|
86
|
+
return left.ruleId.localeCompare(right.ruleId);
|
|
87
|
+
})[0];
|
|
88
|
+
}
|
|
89
|
+
|
|
68
90
|
/**
|
|
69
91
|
* 获取当前配置中各商品的数量限制
|
|
70
92
|
*
|
|
@@ -4,6 +4,8 @@ export declare const ITEM_RULE_ACTION_TYPES: {
|
|
|
4
4
|
readonly QUANTITY_CHECK: "QUANTITY_CHECK";
|
|
5
5
|
/** 预填购物车 */
|
|
6
6
|
readonly PREFILL_CART: "PREFILL_CART";
|
|
7
|
+
/** 加购前过敏信息确认 */
|
|
8
|
+
readonly ALLERGY_CHECK: "ALLERGY_CHECK";
|
|
7
9
|
};
|
|
8
10
|
export type ItemRuleActionType = (typeof ITEM_RULE_ACTION_TYPES)[keyof typeof ITEM_RULE_ACTION_TYPES];
|
|
9
11
|
export declare const ITEM_RULE_TEMPLATES: {
|
|
@@ -63,6 +65,42 @@ export interface TargetItem {
|
|
|
63
65
|
/** 变体 ID */
|
|
64
66
|
product_variant_id?: number;
|
|
65
67
|
}
|
|
68
|
+
/** 策略展示文案,可由调用方按当前 locale 解析。 */
|
|
69
|
+
export type ItemRuleLocalizedText = string | Record<string, string>;
|
|
70
|
+
/** 内联过敏源选项。稳定 id 用于保存选择,label 只负责展示。 */
|
|
71
|
+
export interface AllergyDataSourceItem {
|
|
72
|
+
id: string;
|
|
73
|
+
label: ItemRuleLocalizedText;
|
|
74
|
+
}
|
|
75
|
+
/** 当前仅支持随策略下发的内联过敏源。 */
|
|
76
|
+
export interface AllergyDataSource {
|
|
77
|
+
type: 'inline';
|
|
78
|
+
items: AllergyDataSourceItem[];
|
|
79
|
+
}
|
|
80
|
+
/** 每个目标商品独立持有自己的过敏源,禁止跨商品合并。 */
|
|
81
|
+
export interface AllergyTargetItem extends TargetItem {
|
|
82
|
+
dataSource: AllergyDataSource;
|
|
83
|
+
}
|
|
84
|
+
export type AllergyPromptScope = 'once_per_order_product';
|
|
85
|
+
/** ALLERGY_CHECK Action 的商品级配置。 */
|
|
86
|
+
export interface AllergyCheckConfig {
|
|
87
|
+
targetType: 'product';
|
|
88
|
+
targets: AllergyTargetItem[];
|
|
89
|
+
promptScope: AllergyPromptScope;
|
|
90
|
+
allowNote?: boolean;
|
|
91
|
+
}
|
|
92
|
+
/** 当前商品命中的单条过敏门禁要求。 */
|
|
93
|
+
export interface AllergyRequirement {
|
|
94
|
+
strategyId: string;
|
|
95
|
+
ruleId: string;
|
|
96
|
+
priority: number;
|
|
97
|
+
targetType: 'product';
|
|
98
|
+
product_id: number;
|
|
99
|
+
product_variant_id?: number;
|
|
100
|
+
dataSource: AllergyDataSource;
|
|
101
|
+
promptScope: AllergyPromptScope;
|
|
102
|
+
allowNote: boolean;
|
|
103
|
+
}
|
|
66
104
|
/**
|
|
67
105
|
* 预填商品项
|
|
68
106
|
*/
|
|
@@ -119,6 +157,10 @@ export interface ItemRuleBusinessData {
|
|
|
119
157
|
historicalItems?: CartItemSummary[];
|
|
120
158
|
/** 服务类型(如 'dine-in', 'takeaway') */
|
|
121
159
|
serviceType?: string;
|
|
160
|
+
/** 当前业务渠道(如 'kiosk', 'pos', 'online_store') */
|
|
161
|
+
channel?: string;
|
|
162
|
+
/** 当前正在加入购物车的商品;ALLERGY_CHECK 只读取该商品的 Target。 */
|
|
163
|
+
currentProduct?: Pick<TargetItem, 'product_id' | 'product_variant_id'>;
|
|
122
164
|
/** 当前提交次数(0=首次提交, >0=追加提交) */
|
|
123
165
|
submissionIndex?: number;
|
|
124
166
|
/** 策略配置列表(可选,如果不传则使用 setStrategyConfigs 设置的) */
|
|
@@ -216,6 +258,8 @@ export interface ItemRuleEvaluationResult {
|
|
|
216
258
|
quantityChecks: QuantityCheckResult[];
|
|
217
259
|
/** 需要预填的商品列表 */
|
|
218
260
|
prefillItems: PrefillItemResult[];
|
|
261
|
+
/** 当前商品命中的过敏门禁要求;不同 Action/商品不会合并。 */
|
|
262
|
+
allergyRequirements: AllergyRequirement[];
|
|
219
263
|
/** 所有校验是否全部通过 */
|
|
220
264
|
allPassed: boolean;
|
|
221
265
|
/** 未通过的校验列表 */
|
|
@@ -12,7 +12,9 @@ const ITEM_RULE_ACTION_TYPES = exports.ITEM_RULE_ACTION_TYPES = {
|
|
|
12
12
|
/** 数量校验 */
|
|
13
13
|
QUANTITY_CHECK: 'QUANTITY_CHECK',
|
|
14
14
|
/** 预填购物车 */
|
|
15
|
-
PREFILL_CART: 'PREFILL_CART'
|
|
15
|
+
PREFILL_CART: 'PREFILL_CART',
|
|
16
|
+
/** 加购前过敏信息确认 */
|
|
17
|
+
ALLERGY_CHECK: 'ALLERGY_CHECK'
|
|
16
18
|
};
|
|
17
19
|
// ============================================
|
|
18
20
|
// Rule Template 类型(创建规则时的起始模板)
|
|
@@ -56,6 +58,22 @@ const ITEM_RULE_TEMPLATES = exports.ITEM_RULE_TEMPLATES = {
|
|
|
56
58
|
|
|
57
59
|
/** 目标项 */
|
|
58
60
|
|
|
61
|
+
// ============================================
|
|
62
|
+
// Allergy Check 相关类型
|
|
63
|
+
// ============================================
|
|
64
|
+
|
|
65
|
+
/** 策略展示文案,可由调用方按当前 locale 解析。 */
|
|
66
|
+
|
|
67
|
+
/** 内联过敏源选项。稳定 id 用于保存选择,label 只负责展示。 */
|
|
68
|
+
|
|
69
|
+
/** 当前仅支持随策略下发的内联过敏源。 */
|
|
70
|
+
|
|
71
|
+
/** 每个目标商品独立持有自己的过敏源,禁止跨商品合并。 */
|
|
72
|
+
|
|
73
|
+
/** ALLERGY_CHECK Action 的商品级配置。 */
|
|
74
|
+
|
|
75
|
+
/** 当前商品命中的单条过敏门禁要求。 */
|
|
76
|
+
|
|
59
77
|
// ============================================
|
|
60
78
|
// Prefill Cart 相关类型
|
|
61
79
|
// ============================================
|
|
@@ -19,12 +19,15 @@ export declare class BookingContextModule extends BaseModule implements Module,
|
|
|
19
19
|
protected defaultVersion: string;
|
|
20
20
|
private request;
|
|
21
21
|
private store;
|
|
22
|
+
private otherParams;
|
|
22
23
|
/** 上次成功 loadBookingConfig 的 query key;命中则不再请求。 */
|
|
23
24
|
private lastConfigQueryKey;
|
|
24
25
|
/** 上次成功 loadResources 的 query key(date|bookingIds);命中则不再请求。 */
|
|
25
26
|
private lastResourcesQueryKey;
|
|
26
27
|
constructor(name?: string, version?: string);
|
|
27
28
|
initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
|
|
29
|
+
/** 同步父级解决方案的运行态参数;platform 变化后会自然切换 config endpoint/cache key。 */
|
|
30
|
+
updateOtherParams(params: Record<string, any>): void;
|
|
28
31
|
loadBookingConfig(params?: LoadBookingConfigParams, options?: {
|
|
29
32
|
forceRefresh?: boolean;
|
|
30
33
|
}): Promise<BookingContextConfig | null>;
|
|
@@ -16,6 +16,7 @@ exports.buildBookingResourcesQueryKey = buildBookingResourcesQueryKey;
|
|
|
16
16
|
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
17
17
|
var _BaseModule = require("../BaseModule");
|
|
18
18
|
var _request = require("../../plugins/request");
|
|
19
|
+
var _platform = require("../../utils/platform");
|
|
19
20
|
var _types = require("./types");
|
|
20
21
|
Object.keys(_types).forEach(function (key) {
|
|
21
22
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -52,6 +53,8 @@ const DEFAULT_BOOKING_CONFIG_PARAMS = {
|
|
|
52
53
|
item_type: 'appointment_booking',
|
|
53
54
|
sub_type: 'ticket'
|
|
54
55
|
};
|
|
56
|
+
const BOOKING_CONFIG_ENDPOINT = '/core/board/management/config';
|
|
57
|
+
const H5_BOOKING_CONFIG_ENDPOINT = '/core/board/config';
|
|
55
58
|
const BOARD_CONFIG_CACHE = {
|
|
56
59
|
useCache: true,
|
|
57
60
|
cache: {
|
|
@@ -167,6 +170,26 @@ function buildBookingConfigQueryKey(params = {}) {
|
|
|
167
170
|
});
|
|
168
171
|
return JSON.stringify(sorted);
|
|
169
172
|
}
|
|
173
|
+
function resolveBookingConfigRequest(platform, params = {}) {
|
|
174
|
+
const isH5 = (0, _platform.normalizeRuntimePlatform)(platform) === 'h5';
|
|
175
|
+
const endpoint = isH5 ? H5_BOOKING_CONFIG_ENDPOINT : BOOKING_CONFIG_ENDPOINT;
|
|
176
|
+
const query = isH5 ? {
|
|
177
|
+
item_type: params.item_type || DEFAULT_BOOKING_CONFIG_PARAMS.item_type
|
|
178
|
+
} : {
|
|
179
|
+
...DEFAULT_BOOKING_CONFIG_PARAMS,
|
|
180
|
+
...params
|
|
181
|
+
};
|
|
182
|
+
const keys = Object.keys(query).sort();
|
|
183
|
+
const sortedQuery = {};
|
|
184
|
+
keys.forEach(key => {
|
|
185
|
+
sortedQuery[key] = query[key];
|
|
186
|
+
});
|
|
187
|
+
return {
|
|
188
|
+
endpoint,
|
|
189
|
+
query,
|
|
190
|
+
key: `${endpoint}:${JSON.stringify(sortedQuery)}`
|
|
191
|
+
};
|
|
192
|
+
}
|
|
170
193
|
|
|
171
194
|
/** 稳定序列化资源列表查询(date + bookingIds),用于跳过重复 loadResources。 */
|
|
172
195
|
function buildBookingResourcesQueryKey(params = {}) {
|
|
@@ -181,6 +204,7 @@ class BookingContextModule extends _BaseModule.BaseModule {
|
|
|
181
204
|
store = {
|
|
182
205
|
...EMPTY_STATE
|
|
183
206
|
};
|
|
207
|
+
otherParams = {};
|
|
184
208
|
/** 上次成功 loadBookingConfig 的 query key;命中则不再请求。 */
|
|
185
209
|
lastConfigQueryKey = null;
|
|
186
210
|
/** 上次成功 loadResources 的 query key(date|bookingIds);命中则不再请求。 */
|
|
@@ -194,6 +218,7 @@ class BookingContextModule extends _BaseModule.BaseModule {
|
|
|
194
218
|
if (!this.request) {
|
|
195
219
|
throw new Error('BookingContextModule 需要 request 插件支持');
|
|
196
220
|
}
|
|
221
|
+
this.otherParams = options.otherParams || {};
|
|
197
222
|
this.store = {
|
|
198
223
|
bookingConfig: null,
|
|
199
224
|
resourcesOrigin: [],
|
|
@@ -212,15 +237,17 @@ class BookingContextModule extends _BaseModule.BaseModule {
|
|
|
212
237
|
this.store.date = initialState.date;
|
|
213
238
|
}
|
|
214
239
|
}
|
|
240
|
+
|
|
241
|
+
/** 同步父级解决方案的运行态参数;platform 变化后会自然切换 config endpoint/cache key。 */
|
|
242
|
+
updateOtherParams(params) {
|
|
243
|
+
this.otherParams = params || {};
|
|
244
|
+
}
|
|
215
245
|
async loadBookingConfig(params = {}, options = {}) {
|
|
216
|
-
const
|
|
246
|
+
const requestConfig = resolveBookingConfigRequest(this.otherParams?.platform, params);
|
|
247
|
+
const configKey = requestConfig.key;
|
|
217
248
|
if (!options.forceRefresh && this.store.bookingConfig != null && this.lastConfigQueryKey === configKey) {
|
|
218
249
|
return this.store.bookingConfig;
|
|
219
250
|
}
|
|
220
|
-
const query = {
|
|
221
|
-
...DEFAULT_BOOKING_CONFIG_PARAMS,
|
|
222
|
-
...params
|
|
223
|
-
};
|
|
224
251
|
const sharedKey = buildSharedCacheKey(this.request, configKey);
|
|
225
252
|
if (!options.forceRefresh && sharedBookingConfigCache.has(sharedKey)) {
|
|
226
253
|
const cached = sharedBookingConfigCache.get(sharedKey) ?? null;
|
|
@@ -232,7 +259,7 @@ class BookingContextModule extends _BaseModule.BaseModule {
|
|
|
232
259
|
if (!pending) {
|
|
233
260
|
const requestPromise = (async () => {
|
|
234
261
|
try {
|
|
235
|
-
const res = await this.request.get(
|
|
262
|
+
const res = await this.request.get(requestConfig.endpoint, requestConfig.query, BOARD_CONFIG_CACHE);
|
|
236
263
|
const config = res?.data ?? null;
|
|
237
264
|
sharedBookingConfigCache.set(sharedKey, config);
|
|
238
265
|
return config;
|
|
@@ -293,7 +320,7 @@ class BookingContextModule extends _BaseModule.BaseModule {
|
|
|
293
320
|
* store 内是否已具备与本次 init 入参等价的 config / resources(不再打接口)。
|
|
294
321
|
*/
|
|
295
322
|
isBookingContextReady(params = {}) {
|
|
296
|
-
const configKey =
|
|
323
|
+
const configKey = resolveBookingConfigRequest(this.otherParams?.platform, params.bookingConfigParams).key;
|
|
297
324
|
const dateInput = params.date ?? this.store.date ?? (0, _dayjs.default)();
|
|
298
325
|
const queryDate = toScheduleQueryDate(dateInput);
|
|
299
326
|
const resourcesKey = buildBookingResourcesQueryKey({
|
|
@@ -311,7 +338,7 @@ class BookingContextModule extends _BaseModule.BaseModule {
|
|
|
311
338
|
if (!params.forceRefresh && this.isBookingContextReady(params)) {
|
|
312
339
|
return this.getState();
|
|
313
340
|
}
|
|
314
|
-
const configKey =
|
|
341
|
+
const configKey = resolveBookingConfigRequest(this.otherParams?.platform, params.bookingConfigParams).key;
|
|
315
342
|
const resourcesKey = buildBookingResourcesQueryKey({
|
|
316
343
|
date: queryDate,
|
|
317
344
|
bookingIds: params.bookingIds
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* BookingContext 子模块:承载「预约 UI 上下文」三件套。
|
|
3
3
|
*
|
|
4
|
-
* - bookingConfig:来自 `/core/board/management/config` 的整套预约配置(service_time / resource_tab /
|
|
4
|
+
* - bookingConfig:来自 staff `/core/board/management/config` 或 H5 `/core/board/config` 的整套预约配置(service_time / resource_tab /
|
|
5
5
|
* appointment_subject / subject_require / stock_setting / basic / capacity 等)。
|
|
6
6
|
* - resourcesOrigin / resourcesOriginMap:来自 `/schedule/resource/list` 的资源全集,含 times / event_list /
|
|
7
7
|
* combined_resource 等运行态信息,是 getResourceByIds / getResourceTimeIsUsable 的输入。
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - 默认由 `loadBookingConfig` / `loadResources` 拉取并写入 store;也支持消费方 `set*` 直接灌入(复用 ticketBooking 已拉到的数据)。
|
|
12
12
|
* - 所有读 API 返回浅克隆(数组)或原引用(map / config),避免 UI 写穿。
|
|
13
13
|
*/
|
|
14
|
-
/** `loadBookingConfig`
|
|
14
|
+
/** `loadBookingConfig` 入参;H5 公共接口只消费 `item_type`。 */
|
|
15
15
|
export interface LoadBookingConfigParams {
|
|
16
16
|
item_type?: string;
|
|
17
17
|
sub_type?: string;
|
|
@@ -42,7 +42,7 @@ export interface InitBookingContextParams {
|
|
|
42
42
|
export type BookingContextResource = Record<string, any>;
|
|
43
43
|
export type BookingContextResourceMap = Record<string, BookingContextResource>;
|
|
44
44
|
/**
|
|
45
|
-
* 形参 booking_config(结构来自
|
|
45
|
+
* 形参 booking_config(结构来自 staff management 或 H5 board config 接口的 `data`)。
|
|
46
46
|
* OS 不强制 schema,保留 `Record<string, any>` 兼容现网;常用路径文档化在 SDK docs。
|
|
47
47
|
*/
|
|
48
48
|
export type BookingContextConfig = Record<string, any>;
|
|
@@ -80,7 +80,7 @@ export interface BookingContextModuleAPI {
|
|
|
80
80
|
getState(): BookingContextState;
|
|
81
81
|
/** 一键清空,destroy / 切租户场景用。 */
|
|
82
82
|
clear(): void;
|
|
83
|
-
/**
|
|
83
|
+
/** 按运行平台拉取 board config 并写入 store。 */
|
|
84
84
|
loadBookingConfig(params?: LoadBookingConfigParams): Promise<BookingContextConfig | null>;
|
|
85
85
|
/** 拉取资源全集并写入 store(`/schedule/resource/list`)。 */
|
|
86
86
|
loadResources(params?: LoadBookingResourcesParams): Promise<BookingContextResource[]>;
|
|
@@ -7,7 +7,7 @@ exports.BookingContextEvent = void 0;
|
|
|
7
7
|
/**
|
|
8
8
|
* BookingContext 子模块:承载「预约 UI 上下文」三件套。
|
|
9
9
|
*
|
|
10
|
-
* - bookingConfig:来自 `/core/board/management/config` 的整套预约配置(service_time / resource_tab /
|
|
10
|
+
* - bookingConfig:来自 staff `/core/board/management/config` 或 H5 `/core/board/config` 的整套预约配置(service_time / resource_tab /
|
|
11
11
|
* appointment_subject / subject_require / stock_setting / basic / capacity 等)。
|
|
12
12
|
* - resourcesOrigin / resourcesOriginMap:来自 `/schedule/resource/list` 的资源全集,含 times / event_list /
|
|
13
13
|
* combined_resource 等运行态信息,是 getResourceByIds / getResourceTimeIsUsable 的输入。
|
|
@@ -17,7 +17,7 @@ exports.BookingContextEvent = void 0;
|
|
|
17
17
|
* - 默认由 `loadBookingConfig` / `loadResources` 拉取并写入 store;也支持消费方 `set*` 直接灌入(复用 ticketBooking 已拉到的数据)。
|
|
18
18
|
* - 所有读 API 返回浅克隆(数组)或原引用(map / config),避免 UI 写穿。
|
|
19
19
|
*/
|
|
20
|
-
/** `loadBookingConfig`
|
|
20
|
+
/** `loadBookingConfig` 入参;H5 公共接口只消费 `item_type`。 */
|
|
21
21
|
/** `loadResources` 入参,与 info2 `getResourceList` 一致。 */
|
|
22
22
|
/** `initBookingContext` 入参(BookingTicket 聚合入口)。 */
|
|
23
23
|
/**
|
|
@@ -25,7 +25,7 @@ exports.BookingContextEvent = void 0;
|
|
|
25
25
|
* 这里只声明 Record 形态;具体字段保留 `any`,与 ticketBooking 现网传入的数据形状兼容。
|
|
26
26
|
*/
|
|
27
27
|
/**
|
|
28
|
-
* 形参 booking_config(结构来自
|
|
28
|
+
* 形参 booking_config(结构来自 staff management 或 H5 board config 接口的 `data`)。
|
|
29
29
|
* OS 不强制 schema,保留 `Record<string, any>` 兼容现网;常用路径文档化在 SDK docs。
|
|
30
30
|
*/
|
|
31
31
|
/**
|
|
@@ -23,6 +23,7 @@ export interface OpenDataConfig {
|
|
|
23
23
|
'reservation.auto_confirm'?: boolean;
|
|
24
24
|
'reservation.auto_confirm_mode'?: string;
|
|
25
25
|
'reservation.auto_confirm_delay_seconds'?: number;
|
|
26
|
+
'reservation.time_slice'?: number | string;
|
|
26
27
|
'sale.allow_item_notes'?: boolean;
|
|
27
28
|
'sale.allow_order_notes'?: boolean;
|
|
28
29
|
'sale.enable_item_rules'?: boolean;
|