@pisell/pisellos 2.3.94 → 2.3.96

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 (88) hide show
  1. package/dist/model/strategy/adapter/dataVariant/evaluator.js +13 -2
  2. package/dist/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
  3. package/dist/model/strategy/adapter/itemRule/adapter.js +135 -35
  4. package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
  5. package/dist/model/strategy/adapter/itemRule/evaluator.js +25 -1
  6. package/dist/model/strategy/adapter/itemRule/type.d.ts +44 -0
  7. package/dist/model/strategy/adapter/itemRule/type.js +19 -1
  8. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  9. package/dist/modules/Order/index.d.ts +20 -3
  10. package/dist/modules/Order/index.js +931 -508
  11. package/dist/modules/Order/salesNotes.d.ts +31 -0
  12. package/dist/modules/Order/salesNotes.js +492 -0
  13. package/dist/modules/Order/types.d.ts +91 -5
  14. package/dist/modules/Order/types.js +5 -0
  15. package/dist/modules/Order/utils.d.ts +12 -0
  16. package/dist/modules/Order/utils.js +75 -26
  17. package/dist/modules/ProductList/index.d.ts +2 -1
  18. package/dist/modules/ProductList/index.js +100 -20
  19. package/dist/modules/ProductList/types.d.ts +10 -0
  20. package/dist/modules/SalesSummary/index.js +6 -4
  21. package/dist/server/index.d.ts +6 -0
  22. package/dist/server/index.js +57 -11
  23. package/dist/server/modules/products/index.d.ts +2 -2
  24. package/dist/server/modules/products/index.js +10 -9
  25. package/dist/server/utils/product.d.ts +1 -1
  26. package/dist/server/utils/product.js +186 -22
  27. package/dist/server/utils/small-ticket.js +23 -2
  28. package/dist/solution/BaseSales/index.d.ts +9 -1
  29. package/dist/solution/BaseSales/index.js +894 -706
  30. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +3 -2
  31. package/dist/solution/BookingByStep/index.d.ts +2 -2
  32. package/dist/solution/BookingTicket/utils/orderCustomer.js +3 -2
  33. package/dist/solution/RegisterAndLogin/config.d.ts +9 -3
  34. package/dist/solution/RegisterAndLogin/config.js +95 -40
  35. package/dist/solution/RegisterAndLogin/index.js +4 -1
  36. package/dist/solution/ScanOrder/index.d.ts +1 -0
  37. package/dist/solution/ScanOrder/index.js +31 -27
  38. package/dist/solution/ScanOrder/utils.d.ts +1 -0
  39. package/dist/solution/ScanOrder/utils.js +2 -0
  40. package/dist/solution/UnifiedBookingSales/index.d.ts +15 -2
  41. package/dist/solution/UnifiedBookingSales/index.js +751 -483
  42. package/dist/solution/UnifiedBookingSales/types.d.ts +14 -1
  43. package/dist/solution/VenueBooking/index.d.ts +1 -0
  44. package/dist/solution/VenueBooking/index.js +8 -4
  45. package/lib/model/strategy/adapter/dataVariant/evaluator.js +12 -2
  46. package/lib/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
  47. package/lib/model/strategy/adapter/itemRule/adapter.js +73 -4
  48. package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
  49. package/lib/model/strategy/adapter/itemRule/evaluator.js +23 -1
  50. package/lib/model/strategy/adapter/itemRule/type.d.ts +44 -0
  51. package/lib/model/strategy/adapter/itemRule/type.js +19 -1
  52. package/lib/modules/Order/index.d.ts +20 -3
  53. package/lib/modules/Order/index.js +358 -42
  54. package/lib/modules/Order/salesNotes.d.ts +31 -0
  55. package/lib/modules/Order/salesNotes.js +382 -0
  56. package/lib/modules/Order/types.d.ts +91 -5
  57. package/lib/modules/Order/types.js +4 -0
  58. package/lib/modules/Order/utils.d.ts +12 -0
  59. package/lib/modules/Order/utils.js +68 -16
  60. package/lib/modules/ProductList/index.d.ts +2 -1
  61. package/lib/modules/ProductList/index.js +47 -2
  62. package/lib/modules/ProductList/types.d.ts +10 -0
  63. package/lib/modules/SalesSummary/index.js +3 -1
  64. package/lib/server/index.d.ts +6 -0
  65. package/lib/server/index.js +47 -9
  66. package/lib/server/modules/products/index.d.ts +2 -2
  67. package/lib/server/modules/products/index.js +5 -4
  68. package/lib/server/utils/product.d.ts +1 -1
  69. package/lib/server/utils/product.js +163 -3
  70. package/lib/server/utils/small-ticket.js +22 -1
  71. package/lib/solution/BaseSales/index.d.ts +9 -1
  72. package/lib/solution/BaseSales/index.js +105 -1
  73. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +3 -2
  74. package/lib/solution/BookingByStep/index.d.ts +2 -2
  75. package/lib/solution/BookingTicket/utils/orderCustomer.js +2 -1
  76. package/lib/solution/RegisterAndLogin/config.d.ts +9 -3
  77. package/lib/solution/RegisterAndLogin/config.js +49 -8
  78. package/lib/solution/RegisterAndLogin/index.js +4 -1
  79. package/lib/solution/ScanOrder/index.d.ts +1 -0
  80. package/lib/solution/ScanOrder/index.js +5 -1
  81. package/lib/solution/ScanOrder/utils.d.ts +1 -0
  82. package/lib/solution/ScanOrder/utils.js +1 -0
  83. package/lib/solution/UnifiedBookingSales/index.d.ts +15 -2
  84. package/lib/solution/UnifiedBookingSales/index.js +125 -1
  85. package/lib/solution/UnifiedBookingSales/types.d.ts +14 -1
  86. package/lib/solution/VenueBooking/index.d.ts +1 -0
  87. package/lib/solution/VenueBooking/index.js +5 -1
  88. package/package.json +1 -1
@@ -50,6 +50,7 @@ var _remoteOccupancyCache = require("./remoteOccupancyCache");
50
50
  var _BookingTicket = require("../BookingTicket");
51
51
  var _localClock = require("../../modules/ResourcePlanner/localClock");
52
52
  var _platform = require("../../utils/platform");
53
+ var _itemRule = require("../../model/strategy/adapter/itemRule");
53
54
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
54
55
  const OPEN_DATA_SECTION_CODES = ['sale', 'reservation', 'fulfillment', 'menu', 'workflow', 'basic', 'checkout', 'availability'];
55
56
  const OPEN_DATA_CACHE_TTL = 5 * 60 * 1000;
@@ -82,6 +83,22 @@ function getCandidateStartTime(candidate) {
82
83
  return undefined;
83
84
  }
84
85
  }
86
+ function normalizePositiveIntegerList(value) {
87
+ if (!Array.isArray(value)) return [];
88
+ return Array.from(new Set(value.map(item => normalizePositiveInteger(item)).filter(item => item !== undefined)));
89
+ }
90
+ function toConfiguredBoolean(value) {
91
+ if (typeof value === 'boolean') return value;
92
+ if (typeof value === 'number') return value !== 0;
93
+ if (typeof value === 'string') {
94
+ return ['1', 'true', 'yes', 'y', 'on'].includes(value.trim().toLowerCase());
95
+ }
96
+ return false;
97
+ }
98
+ function normalizeItemRuleStrategyConfigs(value) {
99
+ if (!Array.isArray(value)) return [];
100
+ return value.filter(config => Boolean(config && typeof config === 'object' && config.metadata?.type === 'item_rule'));
101
+ }
85
102
  function isRecord(value) {
86
103
  return !!value && typeof value === 'object' && !Array.isArray(value);
87
104
  }
@@ -1161,11 +1178,15 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1161
1178
  availabilityRemoteResourceQuerySequence = 0;
1162
1179
  availabilityRemoteResourceEpoch = 0;
1163
1180
  availabilityCommitLocks = new Set();
1181
+ allergyItemRuleEvaluator = new _itemRule.ItemRuleEvaluator();
1182
+ allergyItemRuleConfigs = [];
1183
+ allergyItemRuleConfigsPromise = null;
1164
1184
  async initialize(core, options = {}) {
1165
1185
  this.availabilityScheduleCatalog = null;
1166
1186
  this.openDataTarget = null;
1167
1187
  this.availabilityRuntimeOffsetMinutes = (0, _localClock.captureRuntimeOffsetMinutes)();
1168
1188
  this.clearAvailabilityRemoteResourceState();
1189
+ this.resetAllergyItemRuleState();
1169
1190
  await super.initialize(core, options);
1170
1191
  const openDataBusinessCode = String(this.otherParams?.businessCode ?? this.otherParams?.business_code ?? '').trim();
1171
1192
  const openDataChannel = String(this.otherParams?.channel ?? '').trim();
@@ -1310,6 +1331,7 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1310
1331
  cover = false
1311
1332
  } = {}) {
1312
1333
  const previousScope = this.getAvailabilityScopeDescriptor(this.otherParams || {});
1334
+ const previousItemRuleConfig = this.otherParams?.itemRule;
1313
1335
  const explicitlySetsOpenData = Object.prototype.hasOwnProperty.call(params, 'openData');
1314
1336
  await super.setOtherParams(params, {
1315
1337
  cover
@@ -1322,11 +1344,15 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1322
1344
  if (shouldResetAvailabilityState) {
1323
1345
  await this.resetAvailabilityProjectionState('set_other_params_reset');
1324
1346
  }
1347
+ if (shouldResetAvailabilityState || explicitlySetsOpenData || previousItemRuleConfig !== this.otherParams?.itemRule) {
1348
+ this.resetAllergyItemRuleState();
1349
+ }
1325
1350
  }
1326
1351
  async destroy() {
1327
1352
  this.availabilityScheduleCatalog = null;
1328
1353
  this.availabilityRuntimeOffsetMinutes = null;
1329
1354
  await this.resetAvailabilityProjectionState('destroy');
1355
+ this.resetAllergyItemRuleState();
1330
1356
  await super.destroy();
1331
1357
  }
1332
1358
  createAvailabilityContextId() {
@@ -1678,6 +1704,98 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1678
1704
  channel
1679
1705
  });
1680
1706
  }
1707
+ resetAllergyItemRuleState() {
1708
+ this.allergyItemRuleConfigs = [];
1709
+ this.allergyItemRuleConfigsPromise = null;
1710
+ this.allergyItemRuleEvaluator.setStrategyConfigs([]);
1711
+ }
1712
+ async fetchAllergyItemRuleConfigs(strategyModelIds) {
1713
+ if (!strategyModelIds.length) return [];
1714
+ try {
1715
+ const response = await this.request.get('/promotion', {
1716
+ skip: 1,
1717
+ num: 99,
1718
+ status: 'active',
1719
+ ids: strategyModelIds
1720
+ });
1721
+ if (response?.code !== 200 || !Array.isArray(response?.data?.list)) {
1722
+ throw new Error('[UnifiedBookingSales] 商品过敏策略加载失败');
1723
+ }
1724
+ const list = response.data.list;
1725
+ return normalizeItemRuleStrategyConfigs(list.map(item => item?.metadata));
1726
+ } catch (error) {
1727
+ // this.logMethodError('fetchAllergyItemRuleConfigs', error, {
1728
+ // strategyModelIds,
1729
+ // });
1730
+ throw error;
1731
+ }
1732
+ }
1733
+ async ensureAllergyItemRuleConfigsLoaded() {
1734
+ if (this.allergyItemRuleConfigs.length > 0) {
1735
+ return this.allergyItemRuleConfigs;
1736
+ }
1737
+ if (this.allergyItemRuleConfigsPromise) {
1738
+ return this.allergyItemRuleConfigsPromise;
1739
+ }
1740
+ this.allergyItemRuleConfigsPromise = (async () => {
1741
+ const staticConfigs = normalizeItemRuleStrategyConfigs(this.otherParams?.itemRule?.strategyConfigs);
1742
+ if (staticConfigs.length > 0) {
1743
+ this.allergyItemRuleConfigs = staticConfigs;
1744
+ this.allergyItemRuleEvaluator.setStrategyConfigs(staticConfigs);
1745
+ return staticConfigs;
1746
+ }
1747
+ const openData = await this.getOpenData();
1748
+ const enabled = toConfiguredBoolean(openData?.['sale.enable_item_rules']);
1749
+ const strategyModelIds = normalizePositiveIntegerList(openData?.['sale.enabled_item_rules']);
1750
+ if (!enabled || !strategyModelIds.length) {
1751
+ this.allergyItemRuleEvaluator.setStrategyConfigs([]);
1752
+ return [];
1753
+ }
1754
+ const loaded = await this.fetchAllergyItemRuleConfigs(strategyModelIds);
1755
+ this.allergyItemRuleConfigs = loaded;
1756
+ this.allergyItemRuleEvaluator.setStrategyConfigs(loaded);
1757
+ return loaded;
1758
+ })();
1759
+ return this.allergyItemRuleConfigsPromise;
1760
+ }
1761
+
1762
+ /**
1763
+ * 评估当前渠道与商品是否命中 ALLERGY_CHECK。
1764
+ * 只返回优先级最高 Action 中当前商品 Target 的 dataSource,不跨商品或 Action 合并。
1765
+ */
1766
+ async resolveProductAllergyRequirement(params) {
1767
+ const productId = normalizePositiveInteger(params.productId);
1768
+ if (!productId) return null;
1769
+ const strategyConfigs = await this.ensureAllergyItemRuleConfigsLoaded();
1770
+ if (!strategyConfigs.length) return null;
1771
+ const productVariantId = normalizePositiveInteger(params.productVariantId);
1772
+ const runtimeConfig = this.otherParams?.itemRule || {};
1773
+ const runtimePax = runtimeConfig.pax || {};
1774
+ const cartItems = (this.getOrderProducts?.() || []).map(item => ({
1775
+ product_id: Number(item?.product_id ?? item?.id),
1776
+ product_variant_id: Number(item?.product_variant_id ?? 0) || undefined,
1777
+ quantity: Number(item?.num ?? item?.quantity ?? 0)
1778
+ })).filter(item => Number.isFinite(item.product_id) && item.product_id > 0 && Number.isFinite(item.quantity) && item.quantity > 0);
1779
+ return this.allergyItemRuleEvaluator.getAllergyRequirement({
1780
+ pax: {
1781
+ total: Number(runtimePax.total ?? 0) || 0,
1782
+ adult: Number(runtimePax.adult ?? 0) || 0,
1783
+ child: Number(runtimePax.child ?? 0) || 0
1784
+ },
1785
+ cartItems,
1786
+ serviceType: String(runtimeConfig.serviceType ?? this.otherParams?.serviceType ?? ''),
1787
+ channel: String(params.channel ?? this.otherParams?.channel ?? this.otherParams?.platform ?? ''),
1788
+ currentProduct: {
1789
+ product_id: productId,
1790
+ ...(productVariantId ? {
1791
+ product_variant_id: productVariantId
1792
+ } : {})
1793
+ },
1794
+ submissionIndex: Number(runtimeConfig.submissionIndex ?? 0) || 0,
1795
+ strategyConfigs,
1796
+ custom: runtimeConfig.custom
1797
+ });
1798
+ }
1681
1799
 
1682
1800
  /**
1683
1801
  * Load a resource policy without depending on the legacy appointmentBooking solution.
@@ -1714,6 +1832,10 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1714
1832
  await this.core.effects.emit(`${this.name}:onProductsLoaded`, result);
1715
1833
  return result;
1716
1834
  }
1835
+ async queryProducts(params = {}) {
1836
+ if (!this.store.products) throw new Error('[UnifiedBookingSales] products 模块未初始化');
1837
+ return this.store.products.queryProducts(params);
1838
+ }
1717
1839
 
1718
1840
  /** Date-first entry point. It delegates protocol details and cache ownership to ScheduleModule. */
1719
1841
  async loadScheduleAvailableDate(params) {
@@ -3227,7 +3349,9 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
3227
3349
  } else {
3228
3350
  const beforeProductLineUids = new Set((this.getTempOrder()?.products || []).map(line => getProductLineUid(line)).filter(Boolean));
3229
3351
  const beforeBookingUids = new Set((this.getTempOrder()?.bookings || []).map(item => getBookingUid(item)).filter(Boolean));
3230
- const products = await this.addProductToOrder(transformed, booking);
3352
+ const products = await this.addProductToOrder(transformed, booking, params.salesNotes?.length ? {
3353
+ salesNotes: params.salesNotes
3354
+ } : undefined);
3231
3355
  const addedLines = products.filter(line => sameAvailabilityId(line.product_id ?? line.id, refreshedCandidate.productId) && line.metadata?.availability_candidate_key === refreshedCandidate.key && !beforeProductLineUids.has(getProductLineUid(line)));
3232
3356
  productLineUids = addedLines.map(line => getProductLineUid(line)).filter(Boolean);
3233
3357
  const addedBookings = (this.getTempOrder()?.bookings || []).filter(item => item.metadata?.availability_candidate_key === refreshedCandidate.key && !beforeBookingUids.has(getBookingUid(item)));
@@ -1,8 +1,12 @@
1
1
  import type { OpenDataConfig } from '../../modules/OpenData';
2
- import type { ProductListLoadProductsParams } from '../../modules/ProductList';
2
+ import type { ProductListLoadProductsParams, ProductListStoreQueryParams } from '../../modules/ProductList';
3
+ import type { ProductData } from '../../modules/Product/types';
3
4
  import type { LoadScheduleAvailableDateParams } from '../../modules/Schedule/types';
4
5
  import type { AvailabilityDateRange, AvailabilityErrorCode, AvailabilityId, AvailabilityOccupancy, AvailabilityProduct, AvailabilityProjection, AvailabilityQuery, AvailabilityRequirementSelection, AvailabilityResource, AvailabilitySelectionValidationResult, DateAvailabilityQueryResult, GetProductTimeRangesRequest, ProductAvailabilityQueryResult, ProductTimeRange, ProductTimeRangeGroup, ResourceAvailabilityGroup, ResourceAvailabilityRangeGroup, TimeAvailabilityGroup, TimeAvailabilityItem } from '../../modules/ResourcePlanner';
5
6
  import type { BookingTicketState } from '../BookingTicket/types';
7
+ import type { AllergyRequirement } from '../../model/strategy/adapter/itemRule';
8
+ import type { SalesNoteDraftInput } from '../../modules/Order/types';
9
+ export type { ProductListStoreQueryParams } from '../../modules/ProductList';
6
10
  export type { AvailabilityAbsoluteRange, AvailabilityAssignment, AvailabilityCell, AvailabilityDateRange, AvailabilityDisplayRange, AvailabilityErrorCode, AvailabilityId, AvailabilityMode, AvailabilityOccupancy, AvailabilityProduct, AvailabilityProductKind, AvailabilityProjection, AvailabilityProjectionInput, AvailabilityProjectionMeta, AvailabilityQuery, AvailabilityQueryResult, AvailabilityRequirementGroup, AvailabilityRequirementGroupResult, AvailabilityRequirementSelection, AvailabilityResource, AvailabilityResourceOption, AvailabilityResourceType, AvailabilityResourceWindow, AvailabilityScheduleMode, AvailabilityScheduleRef, AvailabilityScheduleRule, AvailabilitySelectionValidationParams, AvailabilitySelectionValidationResult, AvailabilitySessionRange, AvailabilityStatus, DateAvailabilityGroup, DateAvailabilityItem, DateAvailabilityQuery, DateAvailabilityQueryResult, GetProductTimeRangesRequest, ProductAvailabilityGroup, ProductAvailabilityItem, ProductAvailabilityQuery, ProductAvailabilityQueryResult, ProductTimeRange, ProductTimeRangeGroup, QueryAvailabilityBaseRequest, ResourceAvailabilityGroup, ResourceAvailabilityQuery, ResourceAvailabilityQueryResult, ResourceAvailabilityRangeGroup, TimeAvailabilityGroup, TimeAvailabilityItem, TimeAvailabilityQuery, TimeAvailabilityQueryResult, } from '../../modules/ResourcePlanner';
7
11
  export interface UnifiedBookingSalesState extends BookingTicketState {
8
12
  }
@@ -24,6 +28,12 @@ export declare enum UnifiedBookingSalesHooks {
24
28
  export interface UnifiedBookingSalesOtherParams extends Record<string, any> {
25
29
  enableSessionStoragePersist?: boolean;
26
30
  }
31
+ export type UnifiedBookingSalesAllergyRequirement = AllergyRequirement;
32
+ export interface UnifiedBookingSalesResolveProductAllergyRequirementParams {
33
+ productId: number | string;
34
+ productVariantId?: number | string;
35
+ channel?: string;
36
+ }
27
37
  export interface UnifiedBookingSalesLoadOpenDataParams {
28
38
  businessCode: string;
29
39
  channel: string;
@@ -151,6 +161,8 @@ export interface ContextualCommitAvailabilitySelectionParams {
151
161
  requirementSelections: AvailabilityRequirementSelection[];
152
162
  partySize: number;
153
163
  bookingCount?: number;
164
+ /** 新增商品行时与商品、预约在同一次 Order mutation 内写入的 Sales Notes。 */
165
+ salesNotes?: SalesNoteDraftInput[];
154
166
  /** 编辑预约时,允许本次显式报价覆盖已落库订单行的历史价格。 */
155
167
  allowBookingReprice?: boolean;
156
168
  /** 编辑预约重报价后,允许订单模块重新应用已选编辑态折扣。 */
@@ -208,6 +220,7 @@ export interface UnifiedBookingSalesApi {
208
220
  getOpenData: () => Promise<OpenDataConfig | null>;
209
221
  loadScheduleAvailableDate: (params: LoadScheduleAvailableDateParams) => Promise<unknown>;
210
222
  loadProductsByScheduleDate: (params: UnifiedBookingSalesLoadProductsByScheduleDateParams) => Promise<unknown[]>;
223
+ queryProducts: (params?: ProductListStoreQueryParams) => Promise<ProductData[]>;
211
224
  stageRetailProducts: (params: UnifiedBookingSalesStageRetailProductsParams) => Promise<Record<string, any> | null>;
212
225
  addRetailProduct: (params: UnifiedBookingSalesAddRetailProductParams) => Promise<Record<string, any>[]>;
213
226
  prepareAvailabilityProjection: (params: UnifiedBookingSalesPrepareAvailabilityProjectionParams) => Promise<AvailabilityContextRef>;
@@ -15,6 +15,7 @@ interface VenueBookingItemRuleRuntimeConfig {
15
15
  pax?: Partial<PaxInfo>;
16
16
  historicalItems?: CartItemSummary[];
17
17
  serviceType?: string;
18
+ channel?: string;
18
19
  submissionIndex?: number;
19
20
  custom?: Record<string, any>;
20
21
  }
@@ -1758,7 +1758,11 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1758
1758
  return sourceMap;
1759
1759
  }
1760
1760
  getItemRuleRuntimeConfig() {
1761
- return this.itemRuleRuntimeConfig || {};
1761
+ const runtimeConfig = this.itemRuleRuntimeConfig || {};
1762
+ return {
1763
+ ...runtimeConfig,
1764
+ channel: runtimeConfig.channel ?? runtimeConfig.custom?.channel ?? this.otherParams?.channel
1765
+ };
1762
1766
  }
1763
1767
  async ensureItemRuleConfigsLoaded() {
1764
1768
  if (this.itemRuleConfigs.length > 0) return this.itemRuleConfigs;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.3.94",
4
+ "version": "2.3.96",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",