@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.
@@ -14,6 +14,7 @@ export declare function normalizeRawInvoiceTemplateSettings(value: unknown): Inv
14
14
  * 从 OpenData Documents section 的两个扁平字段中构造 Native Invoice 配置。
15
15
  */
16
16
  export declare function normalizeInvoiceTemplateSettings(config: OpenDataConfig | null | undefined): InvoiceTemplateSettings;
17
+ export declare function normalizeInvoiceLayoutFromTemplateSettings(settings: InvoiceTemplateSettings | null | undefined): InvoiceLayoutConfig;
17
18
  /**
18
19
  * 将 invoice_edit.modules 原样投影为 Web Invoice 使用的 module 字段。
19
20
  */
@@ -7,6 +7,7 @@ exports.computeAvailability = computeAvailability;
7
7
  exports.getDefaultInvoiceLayoutConfig = getDefaultInvoiceLayoutConfig;
8
8
  exports.getDefaultInvoiceTemplateSettings = getDefaultInvoiceTemplateSettings;
9
9
  exports.normalizeInvoiceLayoutConfig = normalizeInvoiceLayoutConfig;
10
+ exports.normalizeInvoiceLayoutFromTemplateSettings = normalizeInvoiceLayoutFromTemplateSettings;
10
11
  exports.normalizeInvoiceTemplateSettings = normalizeInvoiceTemplateSettings;
11
12
  exports.normalizeRawInvoiceTemplateSettings = normalizeRawInvoiceTemplateSettings;
12
13
  exports.resolveInvoiceReceiptLocales = resolveInvoiceReceiptLocales;
@@ -118,16 +119,19 @@ function normalizeInvoiceTemplateSettings(config) {
118
119
  template: normalizeInvoiceTemplate(config?.['documents.invoice_template'])
119
120
  });
120
121
  }
122
+ function normalizeInvoiceLayoutFromTemplateSettings(settings) {
123
+ const modules = normalizeRawInvoiceTemplateSettings(settings).modules;
124
+ if (modules.length === 0) return getDefaultInvoiceLayoutConfig();
125
+ return {
126
+ module: modules
127
+ };
128
+ }
121
129
 
122
130
  /**
123
131
  * 将 invoice_edit.modules 原样投影为 Web Invoice 使用的 module 字段。
124
132
  */
125
133
  function normalizeInvoiceLayoutConfig(config) {
126
- const modules = normalizeInvoiceTemplateSettings(config).modules;
127
- if (modules.length === 0) return getDefaultInvoiceLayoutConfig();
128
- return {
129
- module: modules
130
- };
134
+ return normalizeInvoiceLayoutFromTemplateSettings(normalizeInvoiceTemplateSettings(config));
131
135
  }
132
136
  function toBoolean(value) {
133
137
  if (typeof value === 'boolean') return value;
@@ -528,7 +528,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
528
528
  generateIdempotencyToken(): string;
529
529
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
530
530
  createOrder(params: CommitOrderParams['query']): {
531
- type: "virtual" | "appointment_booking";
531
+ type: "appointment_booking" | "virtual";
532
532
  platform: string;
533
533
  sales_channel: string;
534
534
  order_sales_channel: string;
@@ -69,6 +69,7 @@ export interface RequestOptions {
69
69
  customToast?: () => void;
70
70
  cache?: CacheProps;
71
71
  osServer?: boolean;
72
+ isNocobase?: boolean;
72
73
  prefix?: boolean;
73
74
  callback?: (res: any) => void;
74
75
  subscriberId?: string;
@@ -124,7 +125,7 @@ declare class RequestPluginImpl implements RequestPlugin {
124
125
  /**
125
126
  * GET 请求
126
127
  */
127
- get<T = any>(url: string, options?: RequestOptions): Promise<T>;
128
+ get<T = any>(url: string, dataOrOptions?: any, options?: RequestOptions): Promise<T>;
128
129
  /**
129
130
  * POST 请求
130
131
  */
@@ -99,9 +99,10 @@ class RequestPluginImpl {
99
99
  /**
100
100
  * GET 请求
101
101
  */
102
- get(url, options = {}) {
102
+ get(url, dataOrOptions = {}, options) {
103
+ const requestOptions = options ?? dataOrOptions;
103
104
  return this.request({
104
- ...options,
105
+ ...requestOptions,
105
106
  url,
106
107
  method: 'GET'
107
108
  });
@@ -4720,7 +4720,22 @@ class Server {
4720
4720
  if (!this.shouldBuildSmallTicketData(order)) return order;
4721
4721
  if (options?.requireFullyPaid && !this.isSalesOrderFullyPaid(order)) return order;
4722
4722
  try {
4723
- const enrichedOrder = await this.enrichPaymentNamesByCode(order);
4723
+ const normalizedCollections = (0, _orderCollectionIdentity.normalizeOrderCollections)(order, {
4724
+ ensureUid: false
4725
+ });
4726
+ const normalizedOrder = normalizedCollections.order;
4727
+ const collapsedDuplicateCounts = {
4728
+ products: normalizedCollections.stats.product.collapsedDuplicateCount,
4729
+ bookings: normalizedCollections.stats.booking.collapsedDuplicateCount,
4730
+ payments: normalizedCollections.stats.payment.collapsedDuplicateCount
4731
+ };
4732
+ if (Object.values(collapsedDuplicateCounts).some(count => count > 0)) {
4733
+ this.logWarning('withLocalSmallTicketData: 折叠重复订单子项', {
4734
+ order_identifier: normalizedOrder.order_id ?? normalizedOrder.external_sale_number ?? normalizedOrder.shop_order_number ?? null,
4735
+ collapsed_duplicate_counts: collapsedDuplicateCounts
4736
+ });
4737
+ }
4738
+ const enrichedOrder = await this.enrichPaymentNamesByCode(normalizedOrder);
4724
4739
  const productMap = options?.productMap ?? (await this.buildSmallTicketProductMap(enrichedOrder));
4725
4740
  const smallTicketData = (0, _smallTicket.buildSmallTicketData)({
4726
4741
  order: enrichedOrder,
@@ -257,6 +257,22 @@ function normalizeBaseSalesRecordCollections(sourceRecord, options) {
257
257
  }
258
258
  return normalizedRecord;
259
259
  }
260
+ function isValidBaseSalesSmallTicketDataSnapshot(value) {
261
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
262
+ const localeSnapshots = Object.values(value);
263
+ return localeSnapshots.length > 0 && localeSnapshots.some(localeSnapshot => localeSnapshot !== null && typeof localeSnapshot === 'object' && !Array.isArray(localeSnapshot));
264
+ }
265
+ function mergeBaseSalesSmallTicketDataSnapshot(currentValue, loadedValue) {
266
+ if (isValidBaseSalesSmallTicketDataSnapshot(loadedValue)) {
267
+ return (0, _lodashEs.cloneDeep)(loadedValue);
268
+ }
269
+ if (isValidBaseSalesSmallTicketDataSnapshot(currentValue)) {
270
+ return (0, _lodashEs.cloneDeep)(currentValue);
271
+ }
272
+ if (loadedValue !== undefined) return (0, _lodashEs.cloneDeep)(loadedValue);
273
+ if (currentValue !== undefined) return (0, _lodashEs.cloneDeep)(currentValue);
274
+ return undefined;
275
+ }
260
276
  function getBaseSalesMetadataUid(item, metadataKey) {
261
277
  const uid = item?.metadata?.[metadataKey] ?? item?.[metadataKey];
262
278
  if (uid === undefined || uid === null || uid === '') return null;
@@ -296,6 +312,11 @@ function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, str
296
312
  });
297
313
  const uidRemaps = [];
298
314
  const mergedRecord = (0, _lodashEs.mergeWith)(normalizedCurrentTempOrder, normalizedLoadedRecord, (currentValue, loadedValue, key) => {
315
+ // small_ticket_data 是由 Server 一次性生成的完整展示快照,不能递归进入
316
+ // locale 内部继续套用订单集合或普通数组的合并规则。
317
+ if (key === 'small_ticket_data') {
318
+ return mergeBaseSalesSmallTicketDataSnapshot(currentValue, loadedValue);
319
+ }
299
320
  const collectionKind = getBaseSalesOrderCollectionKind(key);
300
321
  if (collectionKind && Array.isArray(loadedValue)) {
301
322
  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
  /**
@@ -221,6 +221,9 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
221
221
  const lastFetchedAt = this.store.openData.getLastFetchedAt();
222
222
  const cachedData = this.store.openData.getOpenData();
223
223
  if (cachedData && this.openDataTarget === target && lastFetchedAt && Date.now() - lastFetchedAt < OPEN_DATA_CACHE_TTL) {
224
+ if (typeof this.store.openData.ensureInvoiceTemplateSettings === 'function') {
225
+ await this.store.openData.ensureInvoiceTemplateSettings(target);
226
+ }
224
227
  this.otherParams.openData = cachedData;
225
228
  return cachedData;
226
229
  }
@@ -182,6 +182,9 @@ class SalesImpl extends _BaseModule.BaseModule {
182
182
  const cachedData = this.invoiceOpenDataModule.getOpenData();
183
183
  const lastFetchedAt = this.invoiceOpenDataModule.getLastFetchedAt();
184
184
  if (cachedData && this.invoiceOpenDataTarget === target && typeof lastFetchedAt === 'number' && Date.now() - lastFetchedAt < INVOICE_OPEN_DATA_CACHE_TTL) {
185
+ if (typeof this.invoiceOpenDataModule.ensureInvoiceTemplateSettings === 'function') {
186
+ await this.invoiceOpenDataModule.ensureInvoiceTemplateSettings(target);
187
+ }
185
188
  return cachedData;
186
189
  }
187
190
  if (this.invoiceOpenDataInFlight) {
@@ -1479,6 +1479,9 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1479
1479
  const cachedData = this.store.openData.getOpenData();
1480
1480
  const lastFetchedAt = this.store.openData.getLastFetchedAt();
1481
1481
  if (!params.force && this.openDataTarget === target && cachedData && lastFetchedAt && Date.now() - lastFetchedAt < OPEN_DATA_CACHE_TTL) {
1482
+ if (typeof this.store.openData.ensureInvoiceTemplateSettings === 'function') {
1483
+ await this.store.openData.ensureInvoiceTemplateSettings(target);
1484
+ }
1482
1485
  return cachedData;
1483
1486
  }
1484
1487
  if (this.loadOpenDataInFlight) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "0.10.20",
4
+ "version": "0.10.21",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",