@pisell/pisellos 0.10.51 → 0.10.53

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.
@@ -55,7 +55,6 @@ var _platform = require("../../utils/platform");
55
55
  var _itemRule = require("../../model/strategy/adapter/itemRule");
56
56
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
57
57
  const OPEN_DATA_SECTION_CODES = ['sale', 'reservation', 'fulfillment', 'menu', 'workflow', 'basic', 'checkout', 'availability', 'documents'];
58
- const OPEN_DATA_CACHE_TTL = 5 * 60 * 1000;
59
58
  function normalizePositiveInteger(value) {
60
59
  const normalized = Number(value);
61
60
  if (!Number.isInteger(normalized) || normalized <= 0) return undefined;
@@ -1200,6 +1199,12 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1200
1199
  defaultVersion = '1.0.0';
1201
1200
  store = {};
1202
1201
  pickupTimingEnabled = true;
1202
+ runtimeOpenDataScope = null;
1203
+ runtimeOpenDataSnapshot = null;
1204
+ runtimeOpenDataModule = null;
1205
+ runtimeOpenDataCore;
1206
+ runtimeOpenDataGeneration = 0;
1207
+ runtimeOpenDataDestroyed = false;
1203
1208
  unifiedProductCatalog = [];
1204
1209
  availabilityRuntimeOffsetMinutes = null;
1205
1210
  availabilityScheduleCatalog = null;
@@ -1219,16 +1224,16 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1219
1224
  allergyItemRuleConfigs = [];
1220
1225
  allergyItemRuleConfigsPromise = null;
1221
1226
  async initialize(core, options = {}) {
1227
+ this.resetRuntimeOpenData();
1228
+ this.runtimeOpenDataDestroyed = false;
1229
+ const openDataGeneration = this.runtimeOpenDataGeneration;
1222
1230
  this.availabilityScheduleCatalog = null;
1223
- this.openDataTarget = null;
1224
1231
  this.availabilityRuntimeOffsetMinutes = (0, _localClock.captureRuntimeOffsetMinutes)();
1225
1232
  this.clearAvailabilityRemoteResourceState();
1226
1233
  this.resetAllergyItemRuleState();
1227
1234
  await super.initialize(core, options);
1228
- const openDataBusinessCode = String(this.otherParams?.businessCode ?? this.otherParams?.business_code ?? '').trim();
1229
- const openDataChannel = String(this.otherParams?.channel ?? '').trim();
1230
- if (this.otherParams?.openData && openDataBusinessCode && openDataChannel) {
1231
- this.openDataTarget = `${openDataBusinessCode}+${openDataChannel}`;
1235
+ if (this.runtimeOpenDataDestroyed || openDataGeneration !== this.runtimeOpenDataGeneration) {
1236
+ throw new Error('Store settings changed. Please try again.');
1232
1237
  }
1233
1238
  this.captureAvailabilityScheduleCatalog();
1234
1239
  }
@@ -1306,7 +1311,7 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1306
1311
  const businessCode = String(this.otherParams?.businessCode ?? this.otherParams?.business_code ?? '').trim();
1307
1312
  const channel = String(this.otherParams?.channel ?? '').trim();
1308
1313
  const currentTarget = businessCode && channel ? `${businessCode}+${channel}` : null;
1309
- let openData = !currentTarget || this.openDataTarget === currentTarget ? this.otherParams?.openData : null;
1314
+ let openData = (!currentTarget || this.openDataTarget === currentTarget) && (this.runtimeOpenDataScope === null || this.runtimeOpenDataScope === this.getRuntimeOpenDataScope()) ? this.otherParams?.openData : null;
1310
1315
  if (!openData && this.store.openData) {
1311
1316
  try {
1312
1317
  openData = await this.getOpenData();
@@ -1370,6 +1375,13 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1370
1375
  const previousScope = this.getAvailabilityScopeDescriptor(this.otherParams || {});
1371
1376
  const previousItemRuleConfig = this.otherParams?.itemRule;
1372
1377
  const explicitlySetsOpenData = Object.prototype.hasOwnProperty.call(params, 'openData');
1378
+ const nextParams = cover ? params : {
1379
+ ...this.otherParams,
1380
+ ...params
1381
+ };
1382
+ if (explicitlySetsOpenData || this.getRuntimeOpenDataScope() !== this.getRuntimeOpenDataScope(nextParams)) {
1383
+ this.clearOpenDataCache();
1384
+ }
1373
1385
  await super.setOtherParams(params, {
1374
1386
  cover
1375
1387
  });
@@ -1386,6 +1398,8 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1386
1398
  }
1387
1399
  }
1388
1400
  async destroy() {
1401
+ this.runtimeOpenDataDestroyed = true;
1402
+ this.clearOpenDataCache();
1389
1403
  this.availabilityScheduleCatalog = null;
1390
1404
  this.availabilityRuntimeOffsetMinutes = null;
1391
1405
  await this.resetAvailabilityProjectionState('destroy');
@@ -1686,52 +1700,117 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1686
1700
  action: this.resolveDiscountAction(this.resolveDiscountOrderIdentity(tempOrder))
1687
1701
  });
1688
1702
  }
1703
+ getRuntimeOpenDataScope(otherParams = this.otherParams) {
1704
+ return JSON.stringify({
1705
+ shop: this.getPickupTimingContextData('shop_id'),
1706
+ appShop: this.appPlugin ? this.getAppData('shop_id') : undefined,
1707
+ tenant: this.appPlugin ? this.getAppData('tenant_id') : undefined,
1708
+ businessCode: String(otherParams?.businessCode ?? otherParams?.business_code ?? '').trim(),
1709
+ channel: String(otherParams?.channel || super.getSubmitOrderSalesChannel()).trim(),
1710
+ platform: (0, _platform.normalizeRuntimePlatform)(otherParams?.platform),
1711
+ timezone: this.getPickupTimingContextData('timezone'),
1712
+ businessTimezone: otherParams?.businessTimezone,
1713
+ cacheId: otherParams === this.otherParams ? this.cacheId : otherParams?.cacheId
1714
+ });
1715
+ }
1716
+ resetRuntimeOpenData() {
1717
+ this.runtimeOpenDataGeneration += 1;
1718
+ this.runtimeOpenDataScope = null;
1719
+ this.runtimeOpenDataSnapshot = null;
1720
+ this.runtimeOpenDataModule = null;
1721
+ this.runtimeOpenDataCore = undefined;
1722
+ this.openDataTarget = null;
1723
+ this.loadOpenDataInFlight = null;
1724
+ this.loadOpenDataInFlightTarget = null;
1725
+ this.otherParams = {
1726
+ ...this.otherParams,
1727
+ openData: null
1728
+ };
1729
+ this.store.openData?.clearCache?.();
1730
+ }
1731
+ async prepareInvoiceTemplateAtSolutionReady(injectedOpenData) {
1732
+ const businessCode = this.getBookingTicketBusinessCode();
1733
+ if (!businessCode || !this.store.openData) return;
1734
+ if (injectedOpenData) {
1735
+ this.otherParams.openData = injectedOpenData;
1736
+ this.openDataTarget = `${businessCode}+${this.getSubmitOrderSalesChannel()}`;
1737
+ }
1738
+ try {
1739
+ await this.loadOpenDataConfig();
1740
+ } catch (error) {
1741
+ console.warn('[UnifiedBookingSales] Invoice 模板预加载失败,使用默认配置', error);
1742
+ }
1743
+ }
1744
+ async loadOpenDataConfig() {
1745
+ const businessCode = this.getBookingTicketBusinessCode();
1746
+ if (!businessCode) return null;
1747
+ return this.loadOpenData({
1748
+ businessCode,
1749
+ channel: this.getSubmitOrderSalesChannel()
1750
+ });
1751
+ }
1689
1752
 
1690
- /**
1691
- * Loads OpenData without borrowing BookingTicket. Cache ownership is tied to the exact
1692
- * business/channel target so a reused solution instance cannot leak another entry's menus.
1693
- */
1753
+ /** A successful configuration belongs to this business runtime until an explicit refresh. */
1694
1754
  async loadOpenData(params) {
1695
- if (!this.store.openData) {
1755
+ const module = this.store.openData;
1756
+ if (!module) {
1696
1757
  throw new Error('[UnifiedBookingSales] openData 模块未初始化');
1697
1758
  }
1759
+ if (this.runtimeOpenDataDestroyed) {
1760
+ throw new Error('Store settings changed. Please try again.');
1761
+ }
1698
1762
  const businessCode = String(params.businessCode || '').trim();
1699
1763
  const channel = String(params.channel || '').trim();
1700
1764
  if (!businessCode || !channel) {
1701
1765
  throw new Error('[UnifiedBookingSales] OpenData 需要 businessCode 与 channel');
1702
1766
  }
1703
1767
  const target = `${businessCode}+${channel}`;
1704
- const cachedData = this.store.openData.getOpenData();
1705
- const lastFetchedAt = this.store.openData.getLastFetchedAt();
1706
- if (!params.force && this.openDataTarget === target && cachedData && lastFetchedAt && Date.now() - lastFetchedAt < OPEN_DATA_CACHE_TTL) {
1707
- if (typeof this.store.openData.ensureInvoiceTemplateSettings === 'function') {
1708
- await this.store.openData.ensureInvoiceTemplateSettings(target);
1768
+ this.otherParams.businessCode = businessCode;
1769
+ this.otherParams.channel = channel;
1770
+ const scope = this.getRuntimeOpenDataScope();
1771
+ if (params.force) {
1772
+ this.clearOpenDataCache();
1773
+ }
1774
+ if (this.runtimeOpenDataScope !== scope || this.runtimeOpenDataModule !== module || this.runtimeOpenDataCore !== this.core) {
1775
+ // Only the first, explicitly injected target may seed a new runtime snapshot.
1776
+ const injectedOpenData = this.runtimeOpenDataScope === null && (!this.openDataTarget || this.openDataTarget === target) && isRecord(this.otherParams.openData) ? this.otherParams.openData : null;
1777
+ if (this.runtimeOpenDataScope !== null) {
1778
+ // The caller's Pickup Timing scope already changes with this runtime scope.
1779
+ this.resetRuntimeOpenData();
1709
1780
  }
1710
- return cachedData;
1781
+ this.runtimeOpenDataScope = scope;
1782
+ this.runtimeOpenDataModule = module;
1783
+ this.runtimeOpenDataCore = this.core;
1784
+ this.runtimeOpenDataSnapshot = injectedOpenData;
1711
1785
  }
1712
1786
  if (this.loadOpenDataInFlight) {
1713
- if (this.loadOpenDataInFlightTarget === target) {
1714
- return await this.loadOpenDataInFlight;
1787
+ return this.loadOpenDataInFlight;
1788
+ }
1789
+ const generation = this.runtimeOpenDataGeneration;
1790
+ const core = this.core;
1791
+ const request = (async () => {
1792
+ let openData = this.runtimeOpenDataSnapshot;
1793
+ if (openData) {
1794
+ await module.ensureInvoiceTemplateSettings?.(target, openData);
1795
+ } else {
1796
+ openData = await module.fetchOpenData({
1797
+ scope: 'board',
1798
+ target,
1799
+ section_code: [...OPEN_DATA_SECTION_CODES]
1800
+ });
1715
1801
  }
1716
- await this.loadOpenDataInFlight;
1717
- return this.loadOpenData(params);
1718
- }
1802
+ if (this.runtimeOpenDataDestroyed || generation !== this.runtimeOpenDataGeneration || scope !== this.getRuntimeOpenDataScope() || module !== this.store.openData || core !== this.core) {
1803
+ throw new Error('Store settings changed. Please try again.');
1804
+ }
1805
+ this.runtimeOpenDataSnapshot = openData;
1806
+ this.openDataTarget = target;
1807
+ this.otherParams.openData = openData;
1808
+ return openData;
1809
+ })();
1719
1810
  this.loadOpenDataInFlightTarget = target;
1720
- const request = this.store.openData.fetchOpenData({
1721
- scope: 'board',
1722
- target,
1723
- section_code: [...OPEN_DATA_SECTION_CODES]
1724
- });
1725
1811
  this.loadOpenDataInFlight = request;
1726
1812
  try {
1727
- const openData = await request;
1728
- if (this.loadOpenDataInFlight === request) {
1729
- this.openDataTarget = target;
1730
- this.otherParams.openData = openData;
1731
- this.otherParams.businessCode = businessCode;
1732
- this.otherParams.channel = channel;
1733
- }
1734
- return openData;
1813
+ return await request;
1735
1814
  } finally {
1736
1815
  if (this.loadOpenDataInFlight === request) {
1737
1816
  this.loadOpenDataInFlight = null;
@@ -1740,27 +1819,14 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1740
1819
  }
1741
1820
  }
1742
1821
  async getOpenData() {
1743
- const businessCode = String(this.otherParams?.businessCode || '').trim();
1744
- const channel = String(this.otherParams?.channel || '').trim();
1745
- if (!businessCode || !channel) return null;
1746
- return this.loadOpenData({
1747
- businessCode,
1748
- channel
1749
- });
1822
+ return this.loadOpenDataConfig();
1750
1823
  }
1751
- async loadPickupTimingOpenData(force) {
1824
+ async loadPickupTimingOpenData(_force) {
1752
1825
  const scope = this.getPickupTimingScope();
1753
- // A fresh validation must not borrow a request started for a previous store/context.
1754
- if (force && this.loadOpenDataInFlight) await this.loadOpenDataInFlight;
1755
- if (scope !== this.getPickupTimingScope()) {
1756
- throw new Error('Store settings changed. Please try again.');
1757
- }
1758
1826
  const businessCode = String(this.otherParams?.businessCode ?? this.otherParams?.business_code ?? '').trim();
1759
- const channel = String(this.getSubmitOrderSalesChannel() ?? '').trim();
1760
1827
  const config = await this.loadOpenData({
1761
1828
  businessCode,
1762
- channel,
1763
- force
1829
+ channel: this.getSubmitOrderSalesChannel()
1764
1830
  });
1765
1831
  if (scope !== this.getPickupTimingScope()) {
1766
1832
  throw new Error('Store settings changed. Please try again.');
@@ -1860,10 +1926,8 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1860
1926
  });
1861
1927
  }
1862
1928
  clearOpenDataCache() {
1863
- this.openDataTarget = null;
1864
- this.loadOpenDataInFlight = null;
1865
- this.loadOpenDataInFlightTarget = null;
1866
- super.clearOpenDataCache();
1929
+ this.resetRuntimeOpenData();
1930
+ this.resetPickupTimingCache();
1867
1931
  }
1868
1932
  async getInvoiceLayoutConfig() {
1869
1933
  const openData = await this.getOpenData();
@@ -1883,7 +1947,7 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1883
1947
  const businessCode = String(this.otherParams?.businessCode || '').trim();
1884
1948
  const channel = String(this.otherParams?.channel || '').trim();
1885
1949
  if (!businessCode || !channel) return false;
1886
- return this.openDataTarget === `${businessCode}+${channel}`;
1950
+ return this.openDataTarget === `${businessCode}+${channel}` && this.runtimeOpenDataScope === this.getRuntimeOpenDataScope();
1887
1951
  }
1888
1952
 
1889
1953
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "0.10.51",
4
+ "version": "0.10.53",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",