@pisell/pisellos 0.10.20 → 0.10.21

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.
@@ -293,6 +293,24 @@ function normalizeBaseSalesRecordCollections(sourceRecord, options) {
293
293
  }
294
294
  return normalizedRecord;
295
295
  }
296
+ function isValidBaseSalesSmallTicketDataSnapshot(value) {
297
+ if (!value || _typeof(value) !== 'object' || Array.isArray(value)) return false;
298
+ var localeSnapshots = Object.values(value);
299
+ return localeSnapshots.length > 0 && localeSnapshots.some(function (localeSnapshot) {
300
+ return localeSnapshot !== null && _typeof(localeSnapshot) === 'object' && !Array.isArray(localeSnapshot);
301
+ });
302
+ }
303
+ function mergeBaseSalesSmallTicketDataSnapshot(currentValue, loadedValue) {
304
+ if (isValidBaseSalesSmallTicketDataSnapshot(loadedValue)) {
305
+ return cloneDeep(loadedValue);
306
+ }
307
+ if (isValidBaseSalesSmallTicketDataSnapshot(currentValue)) {
308
+ return cloneDeep(currentValue);
309
+ }
310
+ if (loadedValue !== undefined) return cloneDeep(loadedValue);
311
+ if (currentValue !== undefined) return cloneDeep(currentValue);
312
+ return undefined;
313
+ }
296
314
  function getBaseSalesMetadataUid(item, metadataKey) {
297
315
  var _item$metadata$metada, _item$metadata;
298
316
  var uid = (_item$metadata$metada = item === null || item === void 0 || (_item$metadata = item.metadata) === null || _item$metadata === void 0 ? void 0 : _item$metadata[metadataKey]) !== null && _item$metadata$metada !== void 0 ? _item$metadata$metada : item === null || item === void 0 ? void 0 : item[metadataKey];
@@ -333,6 +351,11 @@ function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, str
333
351
  });
334
352
  var uidRemaps = [];
335
353
  var mergedRecord = mergeWith(normalizedCurrentTempOrder, normalizedLoadedRecord, function (currentValue, loadedValue, key) {
354
+ // small_ticket_data 是由 Server 一次性生成的完整展示快照,不能递归进入
355
+ // locale 内部继续套用订单集合或普通数组的合并规则。
356
+ if (key === 'small_ticket_data') {
357
+ return mergeBaseSalesSmallTicketDataSnapshot(currentValue, loadedValue);
358
+ }
336
359
  var collectionKind = getBaseSalesOrderCollectionKind(key);
337
360
  if (collectionKind && Array.isArray(loadedValue)) {
338
361
  return mergeBaseSalesOrderCollection(collectionKind, Array.isArray(currentValue) ? currentValue : [], loadedValue, strategy, uidRemaps);
@@ -339,7 +339,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
339
339
  * 获取当前的客户搜索条件
340
340
  * @returns 当前搜索条件
341
341
  */
342
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
342
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
343
343
  /**
344
344
  * 获取客户列表状态(包含滚动加载相关状态)
345
345
  * @returns 客户状态
@@ -458,7 +458,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
458
458
  * 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
459
459
  * 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
460
460
  */
461
- decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
461
+ decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
462
+ action: "reloadCatalog";
463
+ } | {
464
+ action: "add";
465
+ cacheItem: any;
466
+ } | {
467
+ action: "requiresDetail";
468
+ payload: AddProductRequiresDetailPayload;
469
+ } | {
470
+ action: "requiresBookingEdit";
471
+ cacheItem: any;
472
+ payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
473
+ };
462
474
  /** 规格弹窗 callback 后的第二段决策。 */
463
475
  decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
464
476
  /**
@@ -298,30 +298,37 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
298
298
  lastFetchedAt = this.store.openData.getLastFetchedAt();
299
299
  cachedData = this.store.openData.getOpenData();
300
300
  if (!(cachedData && this.openDataTarget === target && lastFetchedAt && Date.now() - lastFetchedAt < OPEN_DATA_CACHE_TTL)) {
301
- _context2.next = 13;
301
+ _context2.next = 16;
302
302
  break;
303
303
  }
304
+ if (!(typeof this.store.openData.ensureInvoiceTemplateSettings === 'function')) {
305
+ _context2.next = 14;
306
+ break;
307
+ }
308
+ _context2.next = 14;
309
+ return this.store.openData.ensureInvoiceTemplateSettings(target);
310
+ case 14:
304
311
  this.otherParams.openData = cachedData;
305
312
  return _context2.abrupt("return", cachedData);
306
- case 13:
313
+ case 16:
307
314
  if (!this.loadOpenDataInFlight) {
308
- _context2.next = 21;
315
+ _context2.next = 24;
309
316
  break;
310
317
  }
311
318
  if (!(this.loadOpenDataInFlightTarget === target)) {
312
- _context2.next = 18;
319
+ _context2.next = 21;
313
320
  break;
314
321
  }
315
- _context2.next = 17;
316
- return this.loadOpenDataInFlight;
317
- case 17:
318
- return _context2.abrupt("return", _context2.sent);
319
- case 18:
320
322
  _context2.next = 20;
321
323
  return this.loadOpenDataInFlight;
322
324
  case 20:
323
- return _context2.abrupt("return", this.loadOpenDataConfig());
325
+ return _context2.abrupt("return", _context2.sent);
324
326
  case 21:
327
+ _context2.next = 23;
328
+ return this.loadOpenDataInFlight;
329
+ case 23:
330
+ return _context2.abrupt("return", this.loadOpenDataConfig());
331
+ case 24:
325
332
  this.loadOpenDataInFlightTarget = target;
326
333
  request = this.store.openData.fetchOpenData({
327
334
  scope: 'board',
@@ -330,10 +337,10 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
330
337
  section_code: [].concat(OPEN_DATA_SECTION_CODES)
331
338
  });
332
339
  this.loadOpenDataInFlight = request;
333
- _context2.prev = 24;
334
- _context2.next = 27;
340
+ _context2.prev = 27;
341
+ _context2.next = 30;
335
342
  return request;
336
- case 27:
343
+ case 30:
337
344
  openDataConfig = _context2.sent;
338
345
  // clearOpenDataCache() 或新请求已接管时,旧响应只能返回给原调用方,不能复活缓存归属。
339
346
  if (this.loadOpenDataInFlight === request) {
@@ -341,18 +348,18 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
341
348
  this.otherParams.openData = openDataConfig;
342
349
  }
343
350
  return _context2.abrupt("return", openDataConfig);
344
- case 30:
345
- _context2.prev = 30;
351
+ case 33:
352
+ _context2.prev = 33;
346
353
  if (this.loadOpenDataInFlight === request) {
347
354
  this.loadOpenDataInFlight = null;
348
355
  this.loadOpenDataInFlightTarget = null;
349
356
  }
350
- return _context2.finish(30);
351
- case 33:
357
+ return _context2.finish(33);
358
+ case 36:
352
359
  case "end":
353
360
  return _context2.stop();
354
361
  }
355
- }, _callee2, this, [[24,, 30, 33]]);
362
+ }, _callee2, this, [[27,, 33, 36]]);
356
363
  }));
357
364
  function loadOpenDataConfig() {
358
365
  return _loadOpenDataConfig.apply(this, arguments);
@@ -275,33 +275,40 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
275
275
  cachedData = this.invoiceOpenDataModule.getOpenData();
276
276
  lastFetchedAt = this.invoiceOpenDataModule.getLastFetchedAt();
277
277
  if (!(cachedData && this.invoiceOpenDataTarget === target && typeof lastFetchedAt === 'number' && Date.now() - lastFetchedAt < INVOICE_OPEN_DATA_CACHE_TTL)) {
278
- _context4.next = 7;
278
+ _context4.next = 10;
279
+ break;
280
+ }
281
+ if (!(typeof this.invoiceOpenDataModule.ensureInvoiceTemplateSettings === 'function')) {
282
+ _context4.next = 9;
279
283
  break;
280
284
  }
285
+ _context4.next = 9;
286
+ return this.invoiceOpenDataModule.ensureInvoiceTemplateSettings(target);
287
+ case 9:
281
288
  return _context4.abrupt("return", cachedData);
282
- case 7:
289
+ case 10:
283
290
  if (!this.invoiceOpenDataInFlight) {
284
- _context4.next = 18;
291
+ _context4.next = 21;
285
292
  break;
286
293
  }
287
294
  if (!(this.invoiceOpenDataInFlightTarget === target)) {
288
- _context4.next = 10;
295
+ _context4.next = 13;
289
296
  break;
290
297
  }
291
298
  return _context4.abrupt("return", this.invoiceOpenDataInFlight);
292
- case 10:
293
- _context4.prev = 10;
294
- _context4.next = 13;
295
- return this.invoiceOpenDataInFlight;
296
299
  case 13:
297
- _context4.next = 17;
300
+ _context4.prev = 13;
301
+ _context4.next = 16;
302
+ return this.invoiceOpenDataInFlight;
303
+ case 16:
304
+ _context4.next = 20;
298
305
  break;
299
- case 15:
300
- _context4.prev = 15;
301
- _context4.t0 = _context4["catch"](10);
302
- case 17:
303
- return _context4.abrupt("return", this.loadInvoiceOpenData(businessCode, channel));
304
306
  case 18:
307
+ _context4.prev = 18;
308
+ _context4.t0 = _context4["catch"](13);
309
+ case 20:
310
+ return _context4.abrupt("return", this.loadInvoiceOpenData(businessCode, channel));
311
+ case 21:
305
312
  request = this.invoiceOpenDataModule.fetchOpenData({
306
313
  scope: 'board',
307
314
  target: target,
@@ -309,28 +316,28 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
309
316
  });
310
317
  this.invoiceOpenDataInFlight = request;
311
318
  this.invoiceOpenDataInFlightTarget = target;
312
- _context4.prev = 21;
313
- _context4.next = 24;
319
+ _context4.prev = 24;
320
+ _context4.next = 27;
314
321
  return request;
315
- case 24:
322
+ case 27:
316
323
  openData = _context4.sent;
317
324
  // clearOpenDataCache() 或后续请求接管后,旧响应不得复活 target 归属。
318
325
  if (this.invoiceOpenDataInFlight === request) {
319
326
  this.invoiceOpenDataTarget = target;
320
327
  }
321
328
  return _context4.abrupt("return", openData);
322
- case 27:
323
- _context4.prev = 27;
329
+ case 30:
330
+ _context4.prev = 30;
324
331
  if (this.invoiceOpenDataInFlight === request) {
325
332
  this.invoiceOpenDataInFlight = null;
326
333
  this.invoiceOpenDataInFlightTarget = null;
327
334
  }
328
- return _context4.finish(27);
329
- case 30:
335
+ return _context4.finish(30);
336
+ case 33:
330
337
  case "end":
331
338
  return _context4.stop();
332
339
  }
333
- }, _callee4, this, [[10, 15], [21,, 27, 30]]);
340
+ }, _callee4, this, [[13, 18], [24,, 30, 33]]);
334
341
  }));
335
342
  function loadInvoiceOpenData(_x4, _x5) {
336
343
  return _loadInvoiceOpenData.apply(this, arguments);
@@ -1937,29 +1937,36 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
1937
1937
  cachedData = this.store.openData.getOpenData();
1938
1938
  lastFetchedAt = this.store.openData.getLastFetchedAt();
1939
1939
  if (!(!params.force && this.openDataTarget === target && cachedData && lastFetchedAt && Date.now() - lastFetchedAt < OPEN_DATA_CACHE_TTL)) {
1940
- _context11.next = 11;
1940
+ _context11.next = 14;
1941
1941
  break;
1942
1942
  }
1943
+ if (!(typeof this.store.openData.ensureInvoiceTemplateSettings === 'function')) {
1944
+ _context11.next = 13;
1945
+ break;
1946
+ }
1947
+ _context11.next = 13;
1948
+ return this.store.openData.ensureInvoiceTemplateSettings(target);
1949
+ case 13:
1943
1950
  return _context11.abrupt("return", cachedData);
1944
- case 11:
1951
+ case 14:
1945
1952
  if (!this.loadOpenDataInFlight) {
1946
- _context11.next = 19;
1953
+ _context11.next = 22;
1947
1954
  break;
1948
1955
  }
1949
1956
  if (!(this.loadOpenDataInFlightTarget === target)) {
1950
- _context11.next = 16;
1957
+ _context11.next = 19;
1951
1958
  break;
1952
1959
  }
1953
- _context11.next = 15;
1954
- return this.loadOpenDataInFlight;
1955
- case 15:
1956
- return _context11.abrupt("return", _context11.sent);
1957
- case 16:
1958
1960
  _context11.next = 18;
1959
1961
  return this.loadOpenDataInFlight;
1960
1962
  case 18:
1961
- return _context11.abrupt("return", this.loadOpenData(params));
1963
+ return _context11.abrupt("return", _context11.sent);
1962
1964
  case 19:
1965
+ _context11.next = 21;
1966
+ return this.loadOpenDataInFlight;
1967
+ case 21:
1968
+ return _context11.abrupt("return", this.loadOpenData(params));
1969
+ case 22:
1963
1970
  this.loadOpenDataInFlightTarget = target;
1964
1971
  request = this.store.openData.fetchOpenData({
1965
1972
  scope: 'board',
@@ -1967,10 +1974,10 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
1967
1974
  section_code: [].concat(OPEN_DATA_SECTION_CODES)
1968
1975
  });
1969
1976
  this.loadOpenDataInFlight = request;
1970
- _context11.prev = 22;
1971
- _context11.next = 25;
1977
+ _context11.prev = 25;
1978
+ _context11.next = 28;
1972
1979
  return request;
1973
- case 25:
1980
+ case 28:
1974
1981
  openData = _context11.sent;
1975
1982
  if (this.loadOpenDataInFlight === request) {
1976
1983
  this.openDataTarget = target;
@@ -1979,18 +1986,18 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
1979
1986
  this.otherParams.channel = channel;
1980
1987
  }
1981
1988
  return _context11.abrupt("return", openData);
1982
- case 28:
1983
- _context11.prev = 28;
1989
+ case 31:
1990
+ _context11.prev = 31;
1984
1991
  if (this.loadOpenDataInFlight === request) {
1985
1992
  this.loadOpenDataInFlight = null;
1986
1993
  this.loadOpenDataInFlightTarget = null;
1987
1994
  }
1988
- return _context11.finish(28);
1989
- case 31:
1995
+ return _context11.finish(31);
1996
+ case 34:
1990
1997
  case "end":
1991
1998
  return _context11.stop();
1992
1999
  }
1993
- }, _callee11, this, [[22,, 28, 31]]);
2000
+ }, _callee11, this, [[25,, 31, 34]]);
1994
2001
  }));
1995
2002
  function loadOpenData(_x7) {
1996
2003
  return _loadOpenData.apply(this, arguments);
@@ -1,46 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- Object.defineProperty(exports, "BUY_X_GET_Y_FREE_STRATEGY", {
7
- enumerable: true,
8
- get: function () {
9
- return _examples.BUY_X_GET_Y_FREE_STRATEGY;
10
- }
11
- });
12
- Object.defineProperty(exports, "ITEM_REWARD_STRATEGY", {
13
- enumerable: true,
14
- get: function () {
15
- return _examples.ITEM_REWARD_STRATEGY;
16
- }
17
- });
18
- Object.defineProperty(exports, "PromotionAdapter", {
19
- enumerable: true,
20
- get: function () {
21
- return _adapter.PromotionAdapter;
22
- }
23
- });
24
- Object.defineProperty(exports, "PromotionEvaluator", {
25
- enumerable: true,
26
- get: function () {
27
- return _evaluator.PromotionEvaluator;
28
- }
29
- });
30
- Object.defineProperty(exports, "X_ITEMS_FOR_Y_PRICE_STRATEGY", {
31
- enumerable: true,
32
- get: function () {
33
- return _examples.X_ITEMS_FOR_Y_PRICE_STRATEGY;
34
- }
35
- });
36
- Object.defineProperty(exports, "default", {
37
- enumerable: true,
38
- get: function () {
39
- return _adapter.default;
40
- }
41
- });
42
- var _evaluator = require("./evaluator");
43
- var _adapter = _interopRequireWildcard(require("./adapter"));
44
- var _examples = require("./examples");
45
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
46
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
1
+ "use strict";
@@ -3,7 +3,7 @@ import { BaseModule } from '../BaseModule';
3
3
  import type { ScheduleModule } from '../Schedule';
4
4
  import type { OpenDataConfig, OpenDataFetchParams, OpenDataAvailabilityResult, InvoiceLayoutConfig, InvoiceTemplateSettings } from './types';
5
5
  export * from './types';
6
- export { computeAvailability, getDefaultInvoiceLayoutConfig, getDefaultInvoiceTemplateSettings, normalizeInvoiceLayoutConfig, normalizeInvoiceTemplateSettings, normalizeRawInvoiceTemplateSettings, resolveInvoiceReceiptLocales, } from './utils';
6
+ export { computeAvailability, getDefaultInvoiceLayoutConfig, getDefaultInvoiceTemplateSettings, normalizeInvoiceLayoutConfig, normalizeInvoiceLayoutFromTemplateSettings, normalizeInvoiceTemplateSettings, normalizeRawInvoiceTemplateSettings, resolveInvoiceReceiptLocales, } from './utils';
7
7
  export declare class OpenDataModule extends BaseModule implements Module {
8
8
  protected defaultName: string;
9
9
  protected defaultVersion: string;
@@ -16,6 +16,9 @@ export declare class OpenDataModule extends BaseModule implements Module {
16
16
  private fatherModule;
17
17
  private otherParams;
18
18
  private fetchRevision;
19
+ private invoiceTemplateCacheRevision;
20
+ private invoiceTemplateDocumentCache;
21
+ private invoiceTemplateDocumentInFlight;
19
22
  constructor(name?: string, version?: string);
20
23
  initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
21
24
  /**
@@ -29,6 +32,12 @@ export declare class OpenDataModule extends BaseModule implements Module {
29
32
  getOpenData(): OpenDataConfig | null;
30
33
  getInvoiceLayoutConfig(): InvoiceLayoutConfig;
31
34
  getInvoiceTemplateSettings(): InvoiceTemplateSettings;
35
+ ensureInvoiceTemplateSettings(target: string): Promise<InvoiceTemplateSettings>;
36
+ private commitInvoiceTemplateSettings;
37
+ private resolveInvoiceTemplateSettings;
38
+ private buildInvoiceTemplateCacheKey;
39
+ private fetchInvoiceTemplateDocument;
40
+ private logInvoiceTemplateDocumentFallback;
32
41
  getLastFetchedAt(): number | null;
33
42
  /** 清除内存与 sessionStorage 镜像中的 OpenData,供宿主切店时调用。 */
34
43
  clearCache(): void;
@@ -9,6 +9,7 @@ var _exportNames = {
9
9
  getDefaultInvoiceLayoutConfig: true,
10
10
  getDefaultInvoiceTemplateSettings: true,
11
11
  normalizeInvoiceLayoutConfig: true,
12
+ normalizeInvoiceLayoutFromTemplateSettings: true,
12
13
  normalizeInvoiceTemplateSettings: true,
13
14
  normalizeRawInvoiceTemplateSettings: true,
14
15
  resolveInvoiceReceiptLocales: true
@@ -38,6 +39,12 @@ Object.defineProperty(exports, "normalizeInvoiceLayoutConfig", {
38
39
  return _utils.normalizeInvoiceLayoutConfig;
39
40
  }
40
41
  });
42
+ Object.defineProperty(exports, "normalizeInvoiceLayoutFromTemplateSettings", {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _utils.normalizeInvoiceLayoutFromTemplateSettings;
46
+ }
47
+ });
41
48
  Object.defineProperty(exports, "normalizeInvoiceTemplateSettings", {
42
49
  enumerable: true,
43
50
  get: function () {
@@ -70,6 +77,25 @@ Object.keys(_types).forEach(function (key) {
70
77
  }
71
78
  });
72
79
  });
80
+ function isRecord(value) {
81
+ return !!value && typeof value === 'object' && !Array.isArray(value);
82
+ }
83
+ function resolveInvoiceDocumentId(value) {
84
+ if (typeof value === 'number') {
85
+ return Number.isSafeInteger(value) && value > 0 ? String(value) : null;
86
+ }
87
+ if (typeof value !== 'string') return null;
88
+ const normalized = value.trim();
89
+ if (!/^\d+$/.test(normalized)) return null;
90
+ const numericId = Number(normalized);
91
+ return Number.isSafeInteger(numericId) && numericId > 0 ? String(numericId) : null;
92
+ }
93
+ function isLegacyInvoiceTemplate(value) {
94
+ if (typeof value !== 'string' || value.trim().length === 0) return false;
95
+ const normalized = value.trim();
96
+ const numericLike = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i;
97
+ return !numericLike.test(normalized);
98
+ }
73
99
  class OpenDataModule extends _BaseModule.BaseModule {
74
100
  defaultName = 'openData';
75
101
  defaultVersion = '1.0.0';
@@ -82,6 +108,9 @@ class OpenDataModule extends _BaseModule.BaseModule {
82
108
  fatherModule;
83
109
  otherParams = {};
84
110
  fetchRevision = 0;
111
+ invoiceTemplateCacheRevision = 0;
112
+ invoiceTemplateDocumentCache = new Map();
113
+ invoiceTemplateDocumentInFlight = new Map();
85
114
  constructor(name, version) {
86
115
  super(name, version);
87
116
  }
@@ -90,6 +119,12 @@ class OpenDataModule extends _BaseModule.BaseModule {
90
119
  this.store = options.store;
91
120
  this.store.data = options.initialState?.data ?? null;
92
121
  this.store.lastFetchedAt = options.initialState?.lastFetchedAt ?? null;
122
+ // Document 解析结果只在当前模块实例内复用。页面刷新后即使恢复了原始
123
+ // OpenData,也必须重新查询一次 NocoBase,以取得当前模板内容。
124
+ this.store.invoiceTemplateSettings = null;
125
+ this.store.invoiceTemplateTarget = null;
126
+ this.store.invoiceTemplateDocumentId = null;
127
+ this.store.invoiceTemplateCacheKey = null;
93
128
  this.otherParams = options.otherParams || {};
94
129
  if (this.otherParams.cacheId) {
95
130
  this.openCache = this.otherParams.openCache ?? false;
@@ -139,10 +174,12 @@ class OpenDataModule extends _BaseModule.BaseModule {
139
174
  throw new Error(response?.message || '获取 OpenData 配置失败');
140
175
  }
141
176
  const data = response?.data || {};
177
+ const resolvedInvoiceTemplate = await this.resolveInvoiceTemplateSettings(data, params.target);
142
178
  // clearCache() 或后续请求发生后,旧响应不得复活已失效的 target 配置。
143
179
  if (fetchRevision === this.fetchRevision) {
144
180
  this.store.data = data;
145
181
  this.store.lastFetchedAt = Date.now();
182
+ this.commitInvoiceTemplateSettings(params.target, resolvedInvoiceTemplate);
146
183
  }
147
184
  return data;
148
185
  }
@@ -150,10 +187,126 @@ class OpenDataModule extends _BaseModule.BaseModule {
150
187
  return this.store.data;
151
188
  }
152
189
  getInvoiceLayoutConfig() {
153
- return (0, _utils.normalizeInvoiceLayoutConfig)(this.store.data);
190
+ return (0, _utils.normalizeInvoiceLayoutFromTemplateSettings)(this.getInvoiceTemplateSettings());
154
191
  }
155
192
  getInvoiceTemplateSettings() {
156
- return (0, _utils.normalizeInvoiceTemplateSettings)(this.store.data);
193
+ if (isRecord(this.store.invoiceTemplateSettings)) {
194
+ const documentId = resolveInvoiceDocumentId(this.store.data?.['documents.invoice_template']);
195
+ if (documentId) {
196
+ const target = this.store.invoiceTemplateTarget;
197
+ if (!target || this.store.invoiceTemplateCacheKey !== this.buildInvoiceTemplateCacheKey(target, documentId)) {
198
+ return (0, _utils.getDefaultInvoiceTemplateSettings)();
199
+ }
200
+ }
201
+ return (0, _utils.normalizeRawInvoiceTemplateSettings)(this.store.invoiceTemplateSettings);
202
+ }
203
+ if (isLegacyInvoiceTemplate(this.store.data?.['documents.invoice_template'])) {
204
+ return (0, _utils.normalizeInvoiceTemplateSettings)(this.store.data);
205
+ }
206
+ return (0, _utils.getDefaultInvoiceTemplateSettings)();
207
+ }
208
+ async ensureInvoiceTemplateSettings(target) {
209
+ const normalizedTarget = String(target || '').trim();
210
+ const config = this.store.data;
211
+ if (!normalizedTarget || !config) {
212
+ return (0, _utils.getDefaultInvoiceTemplateSettings)();
213
+ }
214
+ const fetchRevision = this.fetchRevision;
215
+ const resolved = await this.resolveInvoiceTemplateSettings(config, normalizedTarget);
216
+ if (fetchRevision !== this.fetchRevision || this.store.data !== config) {
217
+ return (0, _utils.getDefaultInvoiceTemplateSettings)();
218
+ }
219
+ this.commitInvoiceTemplateSettings(normalizedTarget, resolved);
220
+ return (0, _utils.normalizeRawInvoiceTemplateSettings)(resolved.settings);
221
+ }
222
+ commitInvoiceTemplateSettings(target, resolved) {
223
+ this.store.invoiceTemplateSettings = (0, _utils.normalizeRawInvoiceTemplateSettings)(resolved.settings);
224
+ this.store.invoiceTemplateTarget = target;
225
+ this.store.invoiceTemplateDocumentId = resolved.documentId;
226
+ this.store.invoiceTemplateCacheKey = resolved.cacheKey;
227
+ }
228
+ async resolveInvoiceTemplateSettings(config, target) {
229
+ const rawTemplate = config['documents.invoice_template'];
230
+ const documentId = resolveInvoiceDocumentId(rawTemplate);
231
+ if (!documentId) {
232
+ return {
233
+ settings: isLegacyInvoiceTemplate(rawTemplate) ? (0, _utils.normalizeInvoiceTemplateSettings)(config) : (0, _utils.getDefaultInvoiceTemplateSettings)(),
234
+ documentId: null,
235
+ cacheKey: null
236
+ };
237
+ }
238
+ const cacheKey = this.buildInvoiceTemplateCacheKey(target, documentId);
239
+ if (this.store.invoiceTemplateTarget === target && this.store.invoiceTemplateDocumentId === documentId && this.store.invoiceTemplateCacheKey === cacheKey && isRecord(this.store.invoiceTemplateSettings)) {
240
+ return {
241
+ settings: (0, _utils.normalizeRawInvoiceTemplateSettings)(this.store.invoiceTemplateSettings),
242
+ documentId,
243
+ cacheKey
244
+ };
245
+ }
246
+ const cachedSettings = this.invoiceTemplateDocumentCache.get(cacheKey);
247
+ if (cachedSettings) {
248
+ return {
249
+ settings: (0, _utils.normalizeRawInvoiceTemplateSettings)(cachedSettings),
250
+ documentId,
251
+ cacheKey
252
+ };
253
+ }
254
+ let request = this.invoiceTemplateDocumentInFlight.get(cacheKey);
255
+ if (!request) {
256
+ const cacheRevision = this.invoiceTemplateCacheRevision;
257
+ request = this.fetchInvoiceTemplateDocument(documentId).catch(error => {
258
+ this.logInvoiceTemplateDocumentFallback(error, target, documentId);
259
+ return (0, _utils.getDefaultInvoiceTemplateSettings)();
260
+ }).then(settings => {
261
+ const normalized = (0, _utils.normalizeRawInvoiceTemplateSettings)(settings);
262
+ if (cacheRevision === this.invoiceTemplateCacheRevision) {
263
+ this.invoiceTemplateDocumentCache.set(cacheKey, normalized);
264
+ }
265
+ return normalized;
266
+ }).finally(() => {
267
+ if (this.invoiceTemplateDocumentInFlight.get(cacheKey) === request) {
268
+ this.invoiceTemplateDocumentInFlight.delete(cacheKey);
269
+ }
270
+ });
271
+ this.invoiceTemplateDocumentInFlight.set(cacheKey, request);
272
+ }
273
+ return {
274
+ settings: await request,
275
+ documentId,
276
+ cacheKey
277
+ };
278
+ }
279
+ buildInvoiceTemplateCacheKey(target, documentId) {
280
+ const getData = this.appPlugin?.getData?.();
281
+ return JSON.stringify([getData?.('tenant_id') ?? null, getData?.('shop_id') ?? null, target, documentId]);
282
+ }
283
+ async fetchInvoiceTemplateDocument(documentId) {
284
+ const response = await this.request.get(`/document:get?filterByTk=${encodeURIComponent(documentId)}`, {}, {
285
+ isNocobase: true,
286
+ prefix: false,
287
+ headers: {
288
+ 'x-data-source': 'pisell2'
289
+ },
290
+ customToast: () => {}
291
+ });
292
+ const document = response?.data;
293
+ if (!document || resolveInvoiceDocumentId(document.id) !== documentId) {
294
+ throw new Error(`Invoice Document ${documentId} 返回的 ID 不匹配`);
295
+ }
296
+ if (document.deleted_at !== null && document.deleted_at !== undefined) {
297
+ throw new Error(`Invoice Document ${documentId} 已被删除`);
298
+ }
299
+ if (!isRecord(document.data) || !isRecord(document.data.template_settings)) {
300
+ throw new Error(`Invoice Document ${documentId} 缺少 template_settings`);
301
+ }
302
+ return (0, _utils.normalizeRawInvoiceTemplateSettings)(document.data.template_settings);
303
+ }
304
+ logInvoiceTemplateDocumentFallback(error, target, documentId) {
305
+ console.warn('[OpenDataModule] Invoice Document 加载失败,使用 DEFAULT', {
306
+ target,
307
+ documentId,
308
+ message: error instanceof Error ? error.message : String(error)
309
+ });
157
310
  }
158
311
  getLastFetchedAt() {
159
312
  return this.store.lastFetchedAt ?? null;
@@ -162,8 +315,15 @@ class OpenDataModule extends _BaseModule.BaseModule {
162
315
  /** 清除内存与 sessionStorage 镜像中的 OpenData,供宿主切店时调用。 */
163
316
  clearCache() {
164
317
  this.fetchRevision += 1;
318
+ this.invoiceTemplateCacheRevision += 1;
319
+ this.invoiceTemplateDocumentCache.clear();
320
+ this.invoiceTemplateDocumentInFlight.clear();
165
321
  this.store.data = null;
166
322
  this.store.lastFetchedAt = null;
323
+ this.store.invoiceTemplateSettings = null;
324
+ this.store.invoiceTemplateTarget = null;
325
+ this.store.invoiceTemplateDocumentId = null;
326
+ this.store.invoiceTemplateCacheKey = null;
167
327
  }
168
328
  checkAvailability(scheduleModule) {
169
329
  const scheduleList = scheduleModule ? scheduleModule?.getScheduleListByIds(this.store.data?.['availability.operating_hours'] || []) : undefined;
@@ -32,6 +32,15 @@ export interface InvoiceTemplateSettings {
32
32
  modules: InvoiceTemplateModuleConfig[];
33
33
  [key: string]: unknown;
34
34
  }
35
+ export interface InvoiceDocumentResponse {
36
+ data?: {
37
+ id?: number | string;
38
+ deleted_at?: string | null;
39
+ data?: {
40
+ template_settings?: unknown;
41
+ };
42
+ };
43
+ }
35
44
  export type RawInvoiceEditConfig = string | {
36
45
  language?: unknown;
37
46
  modules?: unknown;
@@ -79,7 +88,7 @@ export interface OpenDataConfig {
79
88
  label: string;
80
89
  value: number;
81
90
  }>;
82
- 'documents.invoice_template'?: string;
91
+ 'documents.invoice_template'?: string | number;
83
92
  'documents.invoice_edit'?: RawInvoiceEditConfig;
84
93
  /** @deprecated 仅保留旧调用方的类型兼容,Invoice 读取逻辑不再消费该字段。 */
85
94
  'documents.invoice'?: RawInvoiceLayoutConfig;
@@ -92,6 +101,10 @@ export interface OpenDataConfig {
92
101
  export interface OpenDataState {
93
102
  data: OpenDataConfig | null;
94
103
  lastFetchedAt: number | null;
104
+ invoiceTemplateSettings?: InvoiceTemplateSettings | null;
105
+ invoiceTemplateTarget?: string | null;
106
+ invoiceTemplateDocumentId?: string | null;
107
+ invoiceTemplateCacheKey?: string | null;
95
108
  }
96
109
  export interface OpenDataFetchParams {
97
110
  scope: string;