@pisell/pisellos 2.2.210 → 2.2.212

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  2. package/dist/modules/BookingContext/index.d.ts +13 -2
  3. package/dist/modules/BookingContext/index.js +198 -68
  4. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -0
  5. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +3 -0
  6. package/dist/modules/Order/index.d.ts +36 -0
  7. package/dist/modules/Order/index.js +312 -127
  8. package/dist/modules/Order/types.d.ts +4 -1
  9. package/dist/modules/Order/utils.d.ts +1 -0
  10. package/dist/modules/Order/utils.js +12 -7
  11. package/dist/modules/Quotation/index.js +2 -1
  12. package/dist/modules/SalesSummary/index.d.ts +1 -0
  13. package/dist/modules/SalesSummary/index.js +29 -15
  14. package/dist/modules/SurchargeList/index.d.ts +16 -0
  15. package/dist/modules/SurchargeList/index.js +162 -0
  16. package/dist/modules/SurchargeList/types.d.ts +11 -0
  17. package/dist/modules/SurchargeList/types.js +1 -0
  18. package/dist/modules/index.d.ts +1 -0
  19. package/dist/modules/index.js +1 -0
  20. package/dist/server/index.d.ts +8 -0
  21. package/dist/server/index.js +1075 -915
  22. package/dist/server/modules/order/index.d.ts +9 -0
  23. package/dist/server/modules/order/index.js +557 -411
  24. package/dist/server/modules/order/utils/filterBookings.js +25 -2
  25. package/dist/server/modules/order/utils/filterOrders.js +3 -2
  26. package/dist/server/test.json +713 -0
  27. package/dist/server/utils/small-ticket.d.ts +1 -1
  28. package/dist/server/utils/small-ticket.js +1 -1
  29. package/dist/solution/BookingByStep/index.d.ts +1 -1
  30. package/dist/solution/BookingTicket/index.d.ts +1 -1
  31. package/dist/solution/BookingTicket/index.js +22 -20
  32. package/lib/model/strategy/adapter/promotion/index.js +0 -49
  33. package/lib/modules/BookingContext/index.d.ts +13 -2
  34. package/lib/modules/BookingContext/index.js +99 -28
  35. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -0
  36. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +3 -0
  37. package/lib/modules/Order/index.d.ts +36 -0
  38. package/lib/modules/Order/index.js +123 -1
  39. package/lib/modules/Order/types.d.ts +4 -1
  40. package/lib/modules/Order/utils.d.ts +1 -0
  41. package/lib/modules/Order/utils.js +12 -4
  42. package/lib/modules/Quotation/index.js +1 -1
  43. package/lib/modules/SalesSummary/index.d.ts +1 -0
  44. package/lib/modules/SalesSummary/index.js +11 -1
  45. package/lib/modules/SurchargeList/index.d.ts +16 -0
  46. package/lib/modules/SurchargeList/index.js +89 -0
  47. package/lib/modules/SurchargeList/types.d.ts +11 -0
  48. package/lib/modules/SurchargeList/types.js +17 -0
  49. package/lib/modules/index.d.ts +1 -0
  50. package/lib/modules/index.js +2 -0
  51. package/lib/server/index.d.ts +8 -0
  52. package/lib/server/index.js +134 -19
  53. package/lib/server/modules/order/index.d.ts +9 -0
  54. package/lib/server/modules/order/index.js +107 -19
  55. package/lib/server/modules/order/utils/filterBookings.js +17 -2
  56. package/lib/server/modules/order/utils/filterOrders.js +3 -2
  57. package/lib/server/test.json +713 -0
  58. package/lib/server/utils/small-ticket.d.ts +1 -1
  59. package/lib/server/utils/small-ticket.js +1 -35
  60. package/lib/solution/BookingByStep/index.d.ts +1 -1
  61. package/lib/solution/BookingTicket/index.d.ts +1 -1
  62. package/lib/solution/BookingTicket/index.js +12 -7
  63. package/package.json +1 -1
@@ -51,7 +51,7 @@ export interface SmallTicketLocaleData {
51
51
  };
52
52
  customer: SmallTicketItem[];
53
53
  appointment: SmallTicketItem[];
54
- delivery: SmallTicketItem[];
54
+ delivery?: SmallTicketItem[];
55
55
  resources: Array<{
56
56
  id: string | number;
57
57
  code: string;
@@ -127,7 +127,7 @@ function buildLocaleData(params) {
127
127
  }),
128
128
  customer: buildCustomer(order, locale),
129
129
  appointment: buildAppointment(order, locale),
130
- delivery: buildDelivery(order, locale),
130
+ // delivery: buildDelivery(order, locale),
131
131
  resources: buildResources(order, locale),
132
132
  payment_data: buildPaymentData({
133
133
  order: order,
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 1 | 2 | 5 | 3 | 6 | 4;
314
+ weekNum: 0 | 2 | 1 | 5 | 3 | 4 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -310,7 +310,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
310
310
  * 获取当前的客户搜索条件
311
311
  * @returns 当前搜索条件
312
312
  */
313
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
313
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
314
314
  /**
315
315
  * 获取客户列表状态(包含滚动加载相关状态)
316
316
  * @returns 客户状态
@@ -256,7 +256,7 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
256
256
  }
257
257
  return _context3.abrupt("return", res === null || res === void 0 ? void 0 : res.short_number);
258
258
  case 7:
259
- return _context3.abrupt("return", this.getAppData('device_id') || 0);
259
+ return _context3.abrupt("return", String(this.getAppData('device_id') || 0).slice(-2));
260
260
  case 8:
261
261
  case "end":
262
262
  return _context3.stop();
@@ -272,8 +272,8 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
272
272
  key: "configureIdGeneratorFromOpenData",
273
273
  value: function () {
274
274
  var _configureIdGeneratorFromOpenData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
275
- var _openDataConfig, _openDataConfig2, _openDataConfig3, _openDataConfig4, _openDataConfig5;
276
- var openDataConfig, idGenerator, receiptSequenceLength, receiptSequenceStart, prefix, resetReceiptSequenceDaily, operatingDayBoundary, deviceId;
275
+ var _openDataConfig, _openDataConfig2, _openDataConfig3, _openDataConfig4, _openDataConfig5, _openDataConfig6;
276
+ var openDataConfig, idGenerator, receiptSequenceLength, receiptSequenceStart, prefix, shopOrderPrefix, resetReceiptSequenceDaily, operatingDayBoundary, deviceId;
277
277
  return _regeneratorRuntime().wrap(function _callee4$(_context4) {
278
278
  while (1) switch (_context4.prev = _context4.next) {
279
279
  case 0:
@@ -300,17 +300,18 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
300
300
  console.warn('[BookingTicket] idGenerator 插件不可用,跳过配置');
301
301
  return _context4.abrupt("return");
302
302
  case 15:
303
- receiptSequenceLength = this.normalizePositiveInteger((_openDataConfig = openDataConfig) === null || _openDataConfig === void 0 ? void 0 : _openDataConfig['sale.short_number_digits'], 5);
303
+ receiptSequenceLength = this.normalizePositiveInteger((_openDataConfig = openDataConfig) === null || _openDataConfig === void 0 ? void 0 : _openDataConfig['sale.short_number_digits'], 2);
304
304
  receiptSequenceStart = this.normalizePositiveInteger((_openDataConfig2 = openDataConfig) === null || _openDataConfig2 === void 0 ? void 0 : _openDataConfig2['sale.short_number_start_number'], 1);
305
- prefix = this.normalizeIdPrefix((_openDataConfig3 = openDataConfig) === null || _openDataConfig3 === void 0 ? void 0 : _openDataConfig3['sale.short_number_prefix'], 'R');
306
- resetReceiptSequenceDaily = typeof ((_openDataConfig4 = openDataConfig) === null || _openDataConfig4 === void 0 ? void 0 : _openDataConfig4['sale.short_number_daily_reset']) === 'boolean' ? (_openDataConfig5 = openDataConfig) === null || _openDataConfig5 === void 0 ? void 0 : _openDataConfig5['sale.short_number_daily_reset'] : true;
305
+ prefix = this.normalizeIdPrefix((_openDataConfig3 = openDataConfig) === null || _openDataConfig3 === void 0 ? void 0 : _openDataConfig3['sale.short_number_prefix'], '');
306
+ shopOrderPrefix = this.normalizeIdPrefix((_openDataConfig4 = openDataConfig) === null || _openDataConfig4 === void 0 ? void 0 : _openDataConfig4['sale.sale_number_prefix'], '');
307
+ resetReceiptSequenceDaily = typeof ((_openDataConfig5 = openDataConfig) === null || _openDataConfig5 === void 0 ? void 0 : _openDataConfig5['sale.short_number_daily_reset']) === 'boolean' ? (_openDataConfig6 = openDataConfig) === null || _openDataConfig6 === void 0 ? void 0 : _openDataConfig6['sale.short_number_daily_reset'] : false;
307
308
  operatingDayBoundary = this.getAppData('operating_day_boundary');
308
- _context4.next = 22;
309
+ _context4.next = 23;
309
310
  return this.getShortNumberOrDeviceId();
310
- case 22:
311
+ case 23:
311
312
  deviceId = _context4.sent;
312
- _context4.prev = 23;
313
- _context4.next = 26;
313
+ _context4.prev = 24;
314
+ _context4.next = 27;
314
315
  return idGenerator.configure({
315
316
  biz: this.getBookingTicketBusinessCode() || 'ticket',
316
317
  config: {
@@ -321,21 +322,22 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
321
322
  receiptSequenceLength: receiptSequenceLength,
322
323
  resetReceiptSequenceDaily: resetReceiptSequenceDaily,
323
324
  receiptSequenceResetTime: operatingDayBoundary.time,
324
- receiptSequenceStart: receiptSequenceStart
325
+ receiptSequenceStart: receiptSequenceStart,
326
+ shopOrderPrefix: shopOrderPrefix
325
327
  }
326
328
  });
327
- case 26:
328
- _context4.next = 31;
329
+ case 27:
330
+ _context4.next = 32;
329
331
  break;
330
- case 28:
331
- _context4.prev = 28;
332
- _context4.t1 = _context4["catch"](23);
332
+ case 29:
333
+ _context4.prev = 29;
334
+ _context4.t1 = _context4["catch"](24);
333
335
  console.warn('[BookingTicket] idGenerator 配置失败', _context4.t1);
334
- case 31:
336
+ case 32:
335
337
  case "end":
336
338
  return _context4.stop();
337
339
  }
338
- }, _callee4, this, [[1, 7], [23, 28]]);
340
+ }, _callee4, this, [[1, 7], [24, 29]]);
339
341
  }));
340
342
  function configureIdGeneratorFromOpenData() {
341
343
  return _configureIdGeneratorFromOpenData.apply(this, arguments);
@@ -807,8 +809,8 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
807
809
  throw new Error('refreshSalesDetail: tempOrder.order_id 缺失');
808
810
  case 6:
809
811
  return _context11.abrupt("return", this.loadSalesDetail({
810
- orderId: Number(orderId),
811
- forceRemote: true
812
+ orderId: Number(orderId)
813
+ // forceRemote: true,
812
814
  }));
813
815
  case 7:
814
816
  case "end":
@@ -1,49 +0,0 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
27
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
-
29
- // src/model/strategy/adapter/promotion/index.ts
30
- var promotion_exports = {};
31
- __export(promotion_exports, {
32
- BUY_X_GET_Y_FREE_STRATEGY: () => import_examples.BUY_X_GET_Y_FREE_STRATEGY,
33
- PromotionAdapter: () => import_adapter.PromotionAdapter,
34
- PromotionEvaluator: () => import_evaluator.PromotionEvaluator,
35
- X_ITEMS_FOR_Y_PRICE_STRATEGY: () => import_examples.X_ITEMS_FOR_Y_PRICE_STRATEGY,
36
- default: () => import_adapter2.default
37
- });
38
- module.exports = __toCommonJS(promotion_exports);
39
- var import_evaluator = require("./evaluator");
40
- var import_adapter = require("./adapter");
41
- var import_adapter2 = __toESM(require("./adapter"));
42
- var import_examples = require("./examples");
43
- // Annotate the CommonJS export names for ESM import in node:
44
- 0 && (module.exports = {
45
- BUY_X_GET_Y_FREE_STRATEGY,
46
- PromotionAdapter,
47
- PromotionEvaluator,
48
- X_ITEMS_FOR_Y_PRICE_STRATEGY
49
- });
@@ -3,6 +3,13 @@ import { BaseModule } from '../BaseModule';
3
3
  import { BookingContextConfig, BookingContextDateInput, BookingContextModuleAPI, BookingContextResource, BookingContextResourceMap, BookingContextState, InitBookingContextParams, LoadBookingConfigParams, LoadBookingResourcesParams } from './types';
4
4
  export * from './types';
5
5
  export * from './utils';
6
+ /**
7
+ * 清理跨实例共享缓存,仅供单元测试隔离使用。
8
+ *
9
+ * @example
10
+ * __clearBookingContextSharedCacheForTest();
11
+ */
12
+ export declare function __clearBookingContextSharedCacheForTest(): void;
6
13
  /** 稳定序列化 config 查询参数,用于判断是否与上次 loadBookingConfig 一致。 */
7
14
  export declare function buildBookingConfigQueryKey(params?: LoadBookingConfigParams): string;
8
15
  /** 稳定序列化资源列表查询(date + bookingIds),用于跳过重复 loadResources。 */
@@ -18,8 +25,12 @@ export declare class BookingContextModule extends BaseModule implements Module,
18
25
  private lastResourcesQueryKey;
19
26
  constructor(name?: string, version?: string);
20
27
  initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
21
- loadBookingConfig(params?: LoadBookingConfigParams): Promise<BookingContextConfig | null>;
22
- loadResources(params?: LoadBookingResourcesParams): Promise<BookingContextResource[]>;
28
+ loadBookingConfig(params?: LoadBookingConfigParams, options?: {
29
+ forceRefresh?: boolean;
30
+ }): Promise<BookingContextConfig | null>;
31
+ loadResources(params?: LoadBookingResourcesParams, options?: {
32
+ forceRefresh?: boolean;
33
+ }): Promise<BookingContextResource[]>;
23
34
  /**
24
35
  * store 内是否已具备与本次 init 入参等价的 config / resources(不再打接口)。
25
36
  */
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var BookingContext_exports = {};
32
32
  __export(BookingContext_exports, {
33
33
  BookingContextModule: () => BookingContextModule,
34
+ __clearBookingContextSharedCacheForTest: () => __clearBookingContextSharedCacheForTest,
34
35
  buildBookingConfigQueryKey: () => buildBookingConfigQueryKey,
35
36
  buildBookingResourcesQueryKey: () => buildBookingResourcesQueryKey
36
37
  });
@@ -67,6 +68,30 @@ var RESOURCE_LIST_CACHE = {
67
68
  type: "memory"
68
69
  }
69
70
  };
71
+ var requestScopeIds = /* @__PURE__ */ new WeakMap();
72
+ var nextRequestScopeId = 1;
73
+ var sharedBookingConfigCache = /* @__PURE__ */ new Map();
74
+ var sharedBookingConfigPending = /* @__PURE__ */ new Map();
75
+ var sharedResourcesCache = /* @__PURE__ */ new Map();
76
+ var sharedResourcesPending = /* @__PURE__ */ new Map();
77
+ function getRequestScopeId(request) {
78
+ const key = request;
79
+ const existed = requestScopeIds.get(key);
80
+ if (existed)
81
+ return existed;
82
+ const id = nextRequestScopeId++;
83
+ requestScopeIds.set(key, id);
84
+ return id;
85
+ }
86
+ function buildSharedCacheKey(request, queryKey) {
87
+ return `${getRequestScopeId(request)}:${queryKey}`;
88
+ }
89
+ function __clearBookingContextSharedCacheForTest() {
90
+ sharedBookingConfigCache.clear();
91
+ sharedBookingConfigPending.clear();
92
+ sharedResourcesCache.clear();
93
+ sharedResourcesPending.clear();
94
+ }
70
95
  function normalizeDate(input) {
71
96
  if (input === null || input === void 0)
72
97
  return null;
@@ -148,47 +173,85 @@ var BookingContextModule = class extends import_BaseModule.BaseModule {
148
173
  this.store.date = initialState.date;
149
174
  }
150
175
  }
151
- async loadBookingConfig(params = {}) {
176
+ async loadBookingConfig(params = {}, options = {}) {
152
177
  const configKey = buildBookingConfigQueryKey(params);
153
- if (this.store.bookingConfig != null && this.lastConfigQueryKey === configKey) {
178
+ if (!options.forceRefresh && this.store.bookingConfig != null && this.lastConfigQueryKey === configKey) {
154
179
  return this.store.bookingConfig;
155
180
  }
156
181
  const query = {
157
182
  ...DEFAULT_BOOKING_CONFIG_PARAMS,
158
183
  ...params
159
184
  };
160
- const res = await this.request.get(
161
- "/core/board/management/config",
162
- query,
163
- BOARD_CONFIG_CACHE
164
- );
165
- const config = (res == null ? void 0 : res.data) ?? null;
166
- console.log("config123", config);
185
+ const sharedKey = buildSharedCacheKey(this.request, configKey);
186
+ if (!options.forceRefresh && sharedBookingConfigCache.has(sharedKey)) {
187
+ const cached = sharedBookingConfigCache.get(sharedKey) ?? null;
188
+ this.setBookingConfig(cached);
189
+ this.lastConfigQueryKey = configKey;
190
+ return cached;
191
+ }
192
+ let pending = !options.forceRefresh ? sharedBookingConfigPending.get(sharedKey) : void 0;
193
+ if (!pending) {
194
+ const requestPromise = (async () => {
195
+ try {
196
+ const res = await this.request.get(
197
+ "/core/board/management/config",
198
+ query,
199
+ BOARD_CONFIG_CACHE
200
+ );
201
+ const config2 = (res == null ? void 0 : res.data) ?? null;
202
+ sharedBookingConfigCache.set(sharedKey, config2);
203
+ return config2;
204
+ } finally {
205
+ sharedBookingConfigPending.delete(sharedKey);
206
+ }
207
+ })();
208
+ pending = requestPromise;
209
+ sharedBookingConfigPending.set(sharedKey, requestPromise);
210
+ }
211
+ const config = await pending;
167
212
  this.setBookingConfig(config);
168
- this.lastConfigQueryKey = buildBookingConfigQueryKey(params);
213
+ this.lastConfigQueryKey = configKey;
169
214
  return config;
170
215
  }
171
- async loadResources(params = {}) {
216
+ async loadResources(params = {}, options = {}) {
172
217
  const date = toScheduleQueryDate(params.date ?? this.store.date);
173
218
  const resourcesKey = buildBookingResourcesQueryKey({
174
219
  date,
175
220
  bookingIds: params.bookingIds
176
221
  });
177
- if (this.lastResourcesQueryKey === resourcesKey) {
222
+ if (!options.forceRefresh && this.lastResourcesQueryKey === resourcesKey) {
178
223
  return this.getResourcesOrigin();
179
224
  }
180
- const res = await this.request.get(
181
- "/schedule/resource/list",
182
- { date },
183
- RESOURCE_LIST_CACHE
184
- );
185
- const { list } = (0, import_formatResourceList.formatResourceListAndMap)(res == null ? void 0 : res.data, params.bookingIds || []);
225
+ const sharedKey = buildSharedCacheKey(this.request, resourcesKey);
226
+ if (!options.forceRefresh && sharedResourcesCache.has(sharedKey)) {
227
+ const cached = sharedResourcesCache.get(sharedKey) ?? [];
228
+ this.setResources(cached);
229
+ this.lastResourcesQueryKey = resourcesKey;
230
+ return this.getResourcesOrigin();
231
+ }
232
+ let pending = !options.forceRefresh ? sharedResourcesPending.get(sharedKey) : void 0;
233
+ if (!pending) {
234
+ const requestPromise = (async () => {
235
+ try {
236
+ const res = await this.request.get(
237
+ "/schedule/resource/list",
238
+ { date },
239
+ RESOURCE_LIST_CACHE
240
+ );
241
+ const { list: list2 } = (0, import_formatResourceList.formatResourceListAndMap)(res == null ? void 0 : res.data, params.bookingIds || []);
242
+ sharedResourcesCache.set(sharedKey, list2);
243
+ return list2;
244
+ } finally {
245
+ sharedResourcesPending.delete(sharedKey);
246
+ }
247
+ })();
248
+ pending = requestPromise;
249
+ sharedResourcesPending.set(sharedKey, requestPromise);
250
+ }
251
+ const list = await pending;
186
252
  this.setResources(list);
187
- this.lastResourcesQueryKey = buildBookingResourcesQueryKey({
188
- date,
189
- bookingIds: params.bookingIds
190
- });
191
- return list;
253
+ this.lastResourcesQueryKey = resourcesKey;
254
+ return this.getResourcesOrigin();
192
255
  }
193
256
  /**
194
257
  * store 内是否已具备与本次 init 入参等价的 config / resources(不再打接口)。
@@ -220,13 +283,20 @@ var BookingContextModule = class extends import_BaseModule.BaseModule {
220
283
  const needConfig = params.forceRefresh || this.store.bookingConfig == null || this.lastConfigQueryKey !== configKey;
221
284
  const needResources = params.loadResources !== false && (params.forceRefresh || this.lastResourcesQueryKey !== resourcesKey);
222
285
  if (needConfig) {
223
- await this.loadBookingConfig(params.bookingConfigParams);
286
+ await this.loadBookingConfig(params.bookingConfigParams, {
287
+ forceRefresh: params.forceRefresh
288
+ });
224
289
  }
225
290
  if (needResources) {
226
- await this.loadResources({
227
- date: queryDate,
228
- bookingIds: params.bookingIds
229
- });
291
+ await this.loadResources(
292
+ {
293
+ date: queryDate,
294
+ bookingIds: params.bookingIds
295
+ },
296
+ {
297
+ forceRefresh: params.forceRefresh
298
+ }
299
+ );
230
300
  }
231
301
  return this.getState();
232
302
  }
@@ -290,6 +360,7 @@ var BookingContextModule = class extends import_BaseModule.BaseModule {
290
360
  // Annotate the CommonJS export names for ESM import in node:
291
361
  0 && (module.exports = {
292
362
  BookingContextModule,
363
+ __clearBookingContextSharedCacheForTest,
293
364
  buildBookingConfigQueryKey,
294
365
  buildBookingResourcesQueryKey,
295
366
  ...require("./types"),
@@ -67,6 +67,7 @@ export interface BookingMetadataInput {
67
67
  capacity?: number | BookingCapacityMetadataItem[];
68
68
  /** 协议要求始终提交(即使为 null)。 */
69
69
  holder_id: any;
70
+ holder?: any;
70
71
  resource_select_type?: 'single' | 'multiple' | string;
71
72
  }
72
73
  /**
@@ -174,6 +174,9 @@ function cacheItemToBookingInput(cacheItem, options) {
174
174
  if (ext.holder_id !== void 0 && ext.holder_id !== null) {
175
175
  metadata.holder_id = ext.holder_id;
176
176
  }
177
+ if (ext.holder !== void 0) {
178
+ metadata.holder = ext.holder;
179
+ }
177
180
  if (ext.collect_pax !== void 0)
178
181
  metadata.collect_pax = ext.collect_pax;
179
182
  const extendCapacity = normalizeExtendCapacityForMetadata(ext.capacity);
@@ -186,6 +186,41 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
186
186
  private ensureExtend;
187
187
  private captureProductRuntime;
188
188
  private createLinkedProductAndBooking;
189
+ /**
190
+ * booking.holder 是提交真源;metadata.holder 作为详情/回显冗余字段同步保存。
191
+ *
192
+ * @example
193
+ * this.syncBookingMetadataHolder(booking, metadata);
194
+ */
195
+ private syncBookingMetadataHolder;
196
+ /**
197
+ * 从单条 booking 的 holder / metadata 中收集 holder form_record。
198
+ *
199
+ * @example
200
+ * const ids = this.collectBookingHolderRecords(booking);
201
+ */
202
+ private collectBookingHolderRecords;
203
+ /**
204
+ * 按 form_record 顺序读取 booking holder 的主字段名称。
205
+ *
206
+ * @example
207
+ * const names = this.collectBookingHolderNames(booking);
208
+ */
209
+ private collectBookingHolderNames;
210
+ /**
211
+ * 按老 ticketBooking `formatHolder` 语义汇总订单顶层 holder。
212
+ *
213
+ * @example
214
+ * const holder = this.buildTempOrderHolderFromBookings(tempOrder);
215
+ */
216
+ private buildTempOrderHolderFromBookings;
217
+ /**
218
+ * 将 booking 级 holder 汇总到 tempOrder 顶层 holder。
219
+ *
220
+ * @example
221
+ * this.syncTempOrderHolderFromBookings(tempOrder);
222
+ */
223
+ private syncTempOrderHolderFromBookings;
189
224
  private getBookingUniqueIdentificationNumber;
190
225
  private findBookingIndexByUniqueIdentificationNumber;
191
226
  private removeLinkedBookingsForProduct;
@@ -328,6 +363,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
328
363
  }): Promise<T>;
329
364
  private markLocalOrderSynced;
330
365
  private isSubmitResponseRejected;
366
+ private isLocalPendingSubmitResult;
331
367
  private isSubmitErrorResponse;
332
368
  private extractSubmitErrorResponse;
333
369
  private logSubmitBackendRejected;
@@ -1438,6 +1438,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1438
1438
  );
1439
1439
  productMetadata.unique_identification_number = productUid;
1440
1440
  bookingMetadata.unique_identification_number = bookingUid;
1441
+ this.syncBookingMetadataHolder(params.booking, bookingMetadata);
1441
1442
  return {
1442
1443
  productUid,
1443
1444
  bookingUid,
@@ -1459,6 +1460,110 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1459
1460
  }
1460
1461
  };
1461
1462
  }
1463
+ /**
1464
+ * booking.holder 是提交真源;metadata.holder 作为详情/回显冗余字段同步保存。
1465
+ *
1466
+ * @example
1467
+ * this.syncBookingMetadataHolder(booking, metadata);
1468
+ */
1469
+ syncBookingMetadataHolder(booking, metadata) {
1470
+ if ((booking == null ? void 0 : booking.holder) !== void 0) {
1471
+ metadata.holder = booking.holder;
1472
+ }
1473
+ }
1474
+ /**
1475
+ * 从单条 booking 的 holder / metadata 中收集 holder form_record。
1476
+ *
1477
+ * @example
1478
+ * const ids = this.collectBookingHolderRecords(booking);
1479
+ */
1480
+ collectBookingHolderRecords(booking) {
1481
+ var _a;
1482
+ const holder = (booking == null ? void 0 : booking.holder) && typeof booking.holder === "object" ? booking.holder : null;
1483
+ const source = (holder == null ? void 0 : holder.form_record) ?? ((_a = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a.holder_id);
1484
+ const records = Array.isArray(source) ? source : [source];
1485
+ return records.filter((record) => record !== void 0 && record !== null && record !== "");
1486
+ }
1487
+ /**
1488
+ * 按 form_record 顺序读取 booking holder 的主字段名称。
1489
+ *
1490
+ * @example
1491
+ * const names = this.collectBookingHolderNames(booking);
1492
+ */
1493
+ collectBookingHolderNames(booking) {
1494
+ const holder = (booking == null ? void 0 : booking.holder) && typeof booking.holder === "object" ? booking.holder : null;
1495
+ const rawName = holder == null ? void 0 : holder.name;
1496
+ if (Array.isArray(rawName)) {
1497
+ return rawName.map((name) => String(name || "").trim());
1498
+ }
1499
+ if (typeof rawName === "string") {
1500
+ return rawName.split(",").map((name) => name.trim());
1501
+ }
1502
+ return [];
1503
+ }
1504
+ /**
1505
+ * 按老 ticketBooking `formatHolder` 语义汇总订单顶层 holder。
1506
+ *
1507
+ * @example
1508
+ * const holder = this.buildTempOrderHolderFromBookings(tempOrder);
1509
+ */
1510
+ buildTempOrderHolderFromBookings(tempOrder) {
1511
+ var _a, _b;
1512
+ const holderRecords = [];
1513
+ const holderNames = [];
1514
+ let baseHolder = null;
1515
+ const seen = /* @__PURE__ */ new Set();
1516
+ for (const booking of tempOrder.bookings || []) {
1517
+ const holder = (booking == null ? void 0 : booking.holder) && typeof booking.holder === "object" ? booking.holder : null;
1518
+ if (!baseHolder && holder) {
1519
+ baseHolder = holder;
1520
+ }
1521
+ const records = this.collectBookingHolderRecords(booking);
1522
+ const names = this.collectBookingHolderNames(booking);
1523
+ for (const [index, record] of records.entries()) {
1524
+ const key = String(record);
1525
+ if (seen.has(key))
1526
+ continue;
1527
+ seen.add(key);
1528
+ holderRecords.push(record);
1529
+ if (names[index]) {
1530
+ holderNames.push(names[index]);
1531
+ }
1532
+ }
1533
+ }
1534
+ if (!holderRecords.length) {
1535
+ return null;
1536
+ }
1537
+ const nextHolder = {
1538
+ customer_id: (baseHolder == null ? void 0 : baseHolder.customer_id) ?? tempOrder.customer_id,
1539
+ form_id: (baseHolder == null ? void 0 : baseHolder.form_id) ?? ((_a = tempOrder.holder) == null ? void 0 : _a.form_id) ?? 0,
1540
+ form_record: holderRecords
1541
+ };
1542
+ if (holderNames.length) {
1543
+ nextHolder.name = holderNames.join(",");
1544
+ }
1545
+ if ((baseHolder == null ? void 0 : baseHolder.is_source_shop) || ((_b = this.otherParams) == null ? void 0 : _b.isFranchisee)) {
1546
+ nextHolder.is_source_shop = 1;
1547
+ }
1548
+ return nextHolder;
1549
+ }
1550
+ /**
1551
+ * 将 booking 级 holder 汇总到 tempOrder 顶层 holder。
1552
+ *
1553
+ * @example
1554
+ * this.syncTempOrderHolderFromBookings(tempOrder);
1555
+ */
1556
+ syncTempOrderHolderFromBookings(tempOrder) {
1557
+ const bookings = tempOrder.bookings || [];
1558
+ const hasHolderSource = bookings.some((booking) => {
1559
+ var _a;
1560
+ return (booking == null ? void 0 : booking.holder) !== void 0 || ((_a = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a.holder_id) !== void 0;
1561
+ });
1562
+ const nextHolder = this.buildTempOrderHolderFromBookings(tempOrder);
1563
+ if (nextHolder || hasHolderSource || bookings.length === 0) {
1564
+ tempOrder.holder = nextHolder;
1565
+ }
1566
+ }
1462
1567
  getBookingUniqueIdentificationNumber(booking) {
1463
1568
  var _a;
1464
1569
  const uid = (_a = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a.unique_identification_number;
@@ -1996,6 +2101,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1996
2101
  * await this.finalizeProductOrderMutation(tempOrder);
1997
2102
  */
1998
2103
  async finalizeProductOrderMutation(tempOrder) {
2104
+ this.syncTempOrderHolderFromBookings(tempOrder);
1999
2105
  await this.ensureEditDiscountConfigForProductChange(tempOrder);
2000
2106
  await this.applyPromotion();
2001
2107
  this.applyDiscount();
@@ -2360,6 +2466,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2360
2466
  tempOrder.bookings = [...tempOrder.bookings || [], linked.booking];
2361
2467
  }
2362
2468
  tempOrder.products[productIndex] = normalizedProduct;
2469
+ this.syncTempOrderHolderFromBookings(tempOrder);
2363
2470
  this.captureProductRuntime(
2364
2471
  tempOrder,
2365
2472
  updates,
@@ -2458,9 +2565,11 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2458
2565
  unique_identification_number: bookingUid
2459
2566
  }
2460
2567
  };
2568
+ this.syncBookingMetadataHolder(nextBooking, nextBooking.metadata);
2461
2569
  nextBooking.is_all = (0, import_utils.normalizeBookingIsAll)(nextBooking);
2462
2570
  nextBooking.sub_type = (0, import_utils.normalizeBookingSubType)(nextBooking);
2463
2571
  tempOrder.bookings[bookingIndex] = nextBooking;
2572
+ this.syncTempOrderHolderFromBookings(tempOrder);
2464
2573
  this.persistTempOrder();
2465
2574
  return tempOrder.bookings;
2466
2575
  }
@@ -2472,6 +2581,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2472
2581
  * await this.finalizeAfterProductsMutation(tempOrder);
2473
2582
  */
2474
2583
  async finalizeAfterProductsMutation(tempOrder) {
2584
+ this.syncTempOrderHolderFromBookings(tempOrder);
2475
2585
  await this.applyPromotion();
2476
2586
  this.applyDiscount();
2477
2587
  this.sanitizeTempOrderProducts(tempOrder);
@@ -2513,6 +2623,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2513
2623
  const tempOrder = this.ensureTempOrder();
2514
2624
  tempOrder.products = [];
2515
2625
  tempOrder.bookings = [];
2626
+ this.syncTempOrderHolderFromBookings(tempOrder);
2516
2627
  if (tempOrder._extend && typeof tempOrder._extend === "object") {
2517
2628
  tempOrder._extend = {
2518
2629
  ...tempOrder._extend,
@@ -2538,6 +2649,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2538
2649
  businessCode: (params == null ? void 0 : params.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code),
2539
2650
  channel: params == null ? void 0 : params.channel,
2540
2651
  type: params == null ? void 0 : params.type,
2652
+ summary: this.store.summary || (0, import_utils.createEmptySummary)(),
2541
2653
  enhance: (nextPayload) => ({
2542
2654
  ...nextPayload,
2543
2655
  order_number: tempOrder.order_number ?? nextPayload.order_number ?? null,
@@ -2575,6 +2687,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2575
2687
  var _a, _b, _c, _d, _e;
2576
2688
  const tempOrder = this.ensureTempOrder();
2577
2689
  this.persistTempOrder();
2690
+ const latestSummary = await this.recalculateSummary({ createIfMissing: true }) || this.store.summary || (0, import_utils.createEmptySummary)();
2578
2691
  const effectiveCacheId = (params == null ? void 0 : params.cacheId) ?? this.cacheId;
2579
2692
  const hasPaymentOverride = (params == null ? void 0 : params.payments) !== void 0;
2580
2693
  const hasPaymentStatusOverride = (params == null ? void 0 : params.paymentStatus) !== void 0;
@@ -2600,9 +2713,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2600
2713
  businessCode: (params == null ? void 0 : params.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code),
2601
2714
  channel: params == null ? void 0 : params.channel,
2602
2715
  type: params == null ? void 0 : params.type,
2716
+ summary: latestSummary,
2603
2717
  enhance: enhancePayload
2604
2718
  });
2605
- payload.created_at = void 0;
2719
+ if (!payload.created_at) {
2720
+ payload.created_at = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
2721
+ }
2606
2722
  await this.saveDraft();
2607
2723
  let result;
2608
2724
  try {
@@ -2647,6 +2763,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2647
2763
  submittedOrderId,
2648
2764
  (resultRecord == null ? void 0 : resultRecord.data) || resultRecord || {}
2649
2765
  );
2766
+ } else if (this.isLocalPendingSubmitResult(result)) {
2767
+ this.store.syncState = "local";
2650
2768
  } else {
2651
2769
  this.store.syncState = "submitted";
2652
2770
  }
@@ -2666,6 +2784,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2666
2784
  const isErrorSuccess = (response == null ? void 0 : response.success) === false;
2667
2785
  return isErrorCode || isErrorStatus || isErrorSuccess;
2668
2786
  }
2787
+ isLocalPendingSubmitResult(response) {
2788
+ const data = (response == null ? void 0 : response.data) && typeof response.data === "object" ? response.data : response;
2789
+ return Number(data == null ? void 0 : data.need_sync) === 1;
2790
+ }
2669
2791
  isSubmitErrorResponse(response) {
2670
2792
  if (!response || typeof response !== "object")
2671
2793
  return false;