@pisell/pisellos 2.3.17 → 2.3.19

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 (37) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +0 -9
  2. package/dist/modules/Order/index.d.ts +4 -1
  3. package/dist/modules/Order/index.js +56 -29
  4. package/dist/modules/Order/types.d.ts +13 -0
  5. package/dist/modules/Product/index.d.ts +1 -1
  6. package/dist/modules/Rules/index.d.ts +2 -8
  7. package/dist/modules/Rules/index.js +55 -9
  8. package/dist/modules/Rules/types.d.ts +10 -1
  9. package/dist/modules/SalesSummary/index.d.ts +7 -3
  10. package/dist/modules/SalesSummary/index.js +67 -39
  11. package/dist/modules/SalesSummary/types.d.ts +1 -0
  12. package/dist/modules/SurchargeList/index.d.ts +6 -4
  13. package/dist/modules/SurchargeList/index.js +62 -39
  14. package/dist/modules/SurchargeList/types.d.ts +6 -2
  15. package/dist/server/modules/order/index.js +1 -2
  16. package/dist/solution/BaseSales/index.d.ts +6 -0
  17. package/dist/solution/BaseSales/index.js +782 -658
  18. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +2 -1
  19. package/lib/model/strategy/adapter/promotion/index.js +0 -49
  20. package/lib/modules/Order/index.d.ts +4 -1
  21. package/lib/modules/Order/index.js +39 -16
  22. package/lib/modules/Order/types.d.ts +13 -0
  23. package/lib/modules/Product/index.d.ts +1 -1
  24. package/lib/modules/Rules/index.d.ts +2 -8
  25. package/lib/modules/Rules/index.js +57 -6
  26. package/lib/modules/Rules/types.d.ts +10 -1
  27. package/lib/modules/SalesSummary/index.d.ts +7 -3
  28. package/lib/modules/SalesSummary/index.js +28 -11
  29. package/lib/modules/SalesSummary/types.d.ts +1 -0
  30. package/lib/modules/SurchargeList/index.d.ts +6 -4
  31. package/lib/modules/SurchargeList/index.js +41 -21
  32. package/lib/modules/SurchargeList/types.d.ts +6 -2
  33. package/lib/server/modules/order/index.js +1 -2
  34. package/lib/solution/BaseSales/index.d.ts +6 -0
  35. package/lib/solution/BaseSales/index.js +103 -29
  36. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +2 -1
  37. package/package.json +1 -1
@@ -25,15 +25,17 @@ __export(SurchargeList_exports, {
25
25
  module.exports = __toCommonJS(SurchargeList_exports);
26
26
  var import_BaseModule = require("../BaseModule");
27
27
  __reExport(SurchargeList_exports, require("./types"), module.exports);
28
+ var DEFAULT_SURCHARGE_CHANNEL = "online-store";
28
29
  var SurchargeListModule = class extends import_BaseModule.BaseModule {
29
30
  constructor(name, version) {
30
31
  super(name, version);
31
32
  this.defaultName = "surchargeList";
32
33
  this.defaultVersion = "1.0.0";
33
- this.loadingPromise = null;
34
+ this.loadingPromises = /* @__PURE__ */ new Map();
35
+ this.requestVersion = 0;
34
36
  }
35
37
  async initialize(core, options) {
36
- var _a, _b, _c;
38
+ var _a, _b, _c, _d, _e;
37
39
  this.core = core;
38
40
  this.store = options.store;
39
41
  this.request = this.core.getPlugin("request");
@@ -41,44 +43,62 @@ var SurchargeListModule = class extends import_BaseModule.BaseModule {
41
43
  (_a = options.initialState) == null ? void 0 : _a.surchargeList
42
44
  );
43
45
  this.store.surchargeList = hasInitialSurchargeList ? (_b = options.initialState) == null ? void 0 : _b.surchargeList : [];
44
- this.store.isLoaded = Boolean((_c = options.initialState) == null ? void 0 : _c.isLoaded) || hasInitialSurchargeList;
46
+ this.store.channel = ((_c = options.initialState) == null ? void 0 : _c.channel) || ((_d = options.otherParams) == null ? void 0 : _d.channel) || DEFAULT_SURCHARGE_CHANNEL;
47
+ this.store.isLoaded = Boolean((_e = options.initialState) == null ? void 0 : _e.isLoaded) || hasInitialSurchargeList;
45
48
  if (!this.request) {
46
49
  throw new Error("SurchargeListModule 需要 request 插件支持");
47
50
  }
48
51
  }
49
- async getSurchargeList() {
50
- if (this.store.isLoaded)
52
+ resolveChannel(query) {
53
+ return (query == null ? void 0 : query.channel) || DEFAULT_SURCHARGE_CHANNEL;
54
+ }
55
+ async getSurchargeList(query) {
56
+ const channel = this.resolveChannel(query);
57
+ if (this.store.isLoaded && this.store.channel === channel) {
51
58
  return this.store.surchargeList;
52
- if (this.loadingPromise)
53
- return this.loadingPromise;
54
- this.loadingPromise = this.loadSurchargeList();
55
- return this.loadingPromise;
59
+ }
60
+ const loadingPromise = this.loadingPromises.get(channel);
61
+ if (loadingPromise)
62
+ return loadingPromise;
63
+ const nextPromise = this.loadSurchargeList(channel);
64
+ this.loadingPromises.set(channel, nextPromise);
65
+ return nextPromise;
56
66
  }
57
- async refreshSurchargeList() {
58
- this.loadingPromise = this.loadSurchargeList();
59
- return this.loadingPromise;
67
+ async refreshSurchargeList(query) {
68
+ const channel = this.resolveChannel(query);
69
+ const nextPromise = this.loadSurchargeList(channel);
70
+ this.loadingPromises.set(channel, nextPromise);
71
+ return nextPromise;
60
72
  }
61
- async loadSurchargeList() {
73
+ async loadSurchargeList(channel) {
74
+ const currentRequestVersion = ++this.requestVersion;
62
75
  try {
63
76
  const surchargeList = await this.request.get(
64
77
  "/order/custom-surcharge/available/v2",
65
78
  {
66
- channel: "online-store",
79
+ channel,
67
80
  is_assemble_product_data: 1,
68
81
  is_assemble_schedule_data: 1,
69
82
  with: ["relationSchedule"]
70
83
  }
71
84
  );
72
- this.store.surchargeList = (surchargeList == null ? void 0 : surchargeList.data) || [];
73
- this.store.isLoaded = true;
74
- return this.store.surchargeList;
85
+ const nextSurchargeList = (surchargeList == null ? void 0 : surchargeList.data) || [];
86
+ if (currentRequestVersion === this.requestVersion) {
87
+ this.store.surchargeList = nextSurchargeList;
88
+ this.store.channel = channel;
89
+ this.store.isLoaded = true;
90
+ }
91
+ return nextSurchargeList;
75
92
  } catch (error) {
76
93
  console.warn("[SurchargeListModule] 加载附加费配置失败", error);
77
- this.store.surchargeList = [];
78
- this.store.isLoaded = true;
79
- return this.store.surchargeList;
94
+ if (currentRequestVersion === this.requestVersion) {
95
+ this.store.surchargeList = [];
96
+ this.store.channel = channel;
97
+ this.store.isLoaded = true;
98
+ }
99
+ return [];
80
100
  } finally {
81
- this.loadingPromise = null;
101
+ this.loadingPromises.delete(channel);
82
102
  }
83
103
  }
84
104
  };
@@ -4,8 +4,12 @@ export interface SurchargeListItem {
4
4
  export interface SurchargeListState {
5
5
  surchargeList: SurchargeListItem[];
6
6
  isLoaded: boolean;
7
+ channel?: string;
8
+ }
9
+ export interface SurchargeListQuery {
10
+ channel?: string;
7
11
  }
8
12
  export interface SurchargeListModuleAPI {
9
- getSurchargeList(): Promise<SurchargeListItem[]>;
10
- refreshSurchargeList(): Promise<SurchargeListItem[]>;
13
+ getSurchargeList(query?: SurchargeListQuery): Promise<SurchargeListItem[]>;
14
+ refreshSurchargeList(query?: SurchargeListQuery): Promise<SurchargeListItem[]>;
11
15
  }
@@ -308,12 +308,11 @@ var OrderModule = class extends import_BaseModule.BaseModule {
308
308
  };
309
309
  }
310
310
  updateCreateStore() {
311
- var _a;
312
311
  const appPlugin = this.core.getPlugin("app");
313
312
  const app = appPlugin == null ? void 0 : appPlugin.getApp();
314
313
  if (app) {
315
314
  const coreData = app.data.store.getStore().getDataByModel("core");
316
- if (!((_a = this.store.createdAtQuery) == null ? void 0 : _a.sales_time_between) && (coreData == null ? void 0 : coreData.core)) {
315
+ if (coreData == null ? void 0 : coreData.core) {
317
316
  const today = (0, import_dayjs.default)();
318
317
  if (coreData == null ? void 0 : coreData.core.operating_day_boundary) {
319
318
  const operatingDayBoundary = coreData.core.operating_day_boundary;
@@ -49,6 +49,9 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
49
49
  private queuedAutoPaymentSync;
50
50
  private autoPaymentSyncFlushing;
51
51
  private autoPaymentSyncTimer;
52
+ private salesDetailLoadInFlight;
53
+ private serverOrderChangeUnsubscribe;
54
+ private serverOrderChangeHydrateInFlight;
52
55
  constructor(name?: string, version?: string);
53
56
  /**
54
57
  * 子类可覆盖此方法以追加/收敛要注册的子模块。
@@ -69,6 +72,9 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
69
72
  * 记录错误日志
70
73
  */
71
74
  private logError;
75
+ private isCurrentSalesOrderRecord;
76
+ private syncCurrentSalesDetailFromServerOrderChange;
77
+ private registerServerOrderChangeSync;
72
78
  private hydrateOrderPaymentNames;
73
79
  get payment(): PaymentModule | undefined;
74
80
  private getCurrentOrderCustomerId;
@@ -45,6 +45,7 @@ __reExport(BaseSales_exports, require("./types"), module.exports);
45
45
  var import_Quotation = require("../../modules/Quotation");
46
46
  var import_transformBaseProductToOrderProduct = require("./utils/transformBaseProductToOrderProduct");
47
47
  var import_quotationPrice = require("./utils/quotationPrice");
48
+ var SERVER_ORDER_CHANGED_EVENT = "order:onOrdersChanged";
48
49
  function isBaseSalesManualProductDiscountProduct(product) {
49
50
  var _a, _b;
50
51
  return ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.is_manual_discount) === true || ((_b = product == null ? void 0 : product.metadata) == null ? void 0 : _b.is_manual_discount) === 1 || ((product == null ? void 0 : product.discount_list) || []).some((item) => (item == null ? void 0 : item.type) === "product");
@@ -82,6 +83,18 @@ function getBaseSalesUniqueArrayMetadataKey(key) {
82
83
  return "unique_payment_number";
83
84
  return null;
84
85
  }
86
+ function isSameBaseSalesOrderRecord(left, right) {
87
+ if (!left || !right || typeof left !== "object" || typeof right !== "object")
88
+ return false;
89
+ const leftIdentities = new Set(
90
+ [left.order_id, left.id, left.external_sale_number, left.order_number].filter((value) => value !== void 0 && value !== null && value !== "").map(String)
91
+ );
92
+ if (leftIdentities.size === 0)
93
+ return false;
94
+ return [right.order_id, right.id, right.external_sale_number, right.order_number].some(
95
+ (value) => value !== void 0 && value !== null && value !== "" && leftIdentities.has(String(value))
96
+ );
97
+ }
85
98
  function getBaseSalesMetadataUid(item, metadataKey) {
86
99
  var _a;
87
100
  const uid = ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a[metadataKey]) ?? (item == null ? void 0 : item[metadataKey]);
@@ -159,6 +172,9 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
159
172
  this.queuedAutoPaymentSync = false;
160
173
  this.autoPaymentSyncFlushing = false;
161
174
  this.autoPaymentSyncTimer = null;
175
+ this.salesDetailLoadInFlight = false;
176
+ this.serverOrderChangeUnsubscribe = null;
177
+ this.serverOrderChangeHydrateInFlight = null;
162
178
  }
163
179
  /**
164
180
  * 子类可覆盖此方法以追加/收敛要注册的子模块。
@@ -223,6 +239,53 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
223
239
  });
224
240
  }
225
241
  }
242
+ isCurrentSalesOrderRecord(order) {
243
+ var _a, _b;
244
+ const currentTempOrder = (_b = (_a = this.store.order) == null ? void 0 : _a.getTempOrder) == null ? void 0 : _b.call(_a);
245
+ const currentRecords = [
246
+ currentTempOrder,
247
+ this.currentSalesDetail
248
+ ].filter(Boolean);
249
+ return currentRecords.some((record) => isSameBaseSalesOrderRecord(record, order));
250
+ }
251
+ async syncCurrentSalesDetailFromServerOrderChange(payload) {
252
+ const changedOrders = Array.isArray(payload) ? payload : Array.isArray(payload == null ? void 0 : payload.changedOrders) ? payload.changedOrders : (payload == null ? void 0 : payload.data) && typeof payload.data === "object" ? [payload.data] : [];
253
+ if (this.salesDetailLoadInFlight || this.serverOrderChangeHydrateInFlight)
254
+ return;
255
+ const changedOrder = changedOrders.find(
256
+ (order) => this.isCurrentSalesOrderRecord(order)
257
+ );
258
+ if (!changedOrder)
259
+ return;
260
+ if (!this.store.order)
261
+ return;
262
+ this.serverOrderChangeHydrateInFlight = (async () => {
263
+ const sales = await this.store.order.hydrateTempOrderFromRecord(changedOrder, {
264
+ recalcOnHydrate: false
265
+ });
266
+ this.currentSalesDetail = sales;
267
+ await this.core.effects.emit(`${this.name}:onSalesOrderLoaded`, { sales });
268
+ })();
269
+ try {
270
+ await this.serverOrderChangeHydrateInFlight;
271
+ } finally {
272
+ this.serverOrderChangeHydrateInFlight = null;
273
+ }
274
+ }
275
+ registerServerOrderChangeSync() {
276
+ var _a, _b;
277
+ (_a = this.serverOrderChangeUnsubscribe) == null ? void 0 : _a.call(this);
278
+ const effects = (_b = this.core) == null ? void 0 : _b.effects;
279
+ if (!effects || typeof effects.on !== "function")
280
+ return;
281
+ this.serverOrderChangeUnsubscribe = effects.on(SERVER_ORDER_CHANGED_EVENT, (payload) => {
282
+ void this.syncCurrentSalesDetailFromServerOrderChange(payload).catch((error) => {
283
+ this.logError("sync sales detail from server order change failed", {
284
+ error: error instanceof Error ? error.message : String(error)
285
+ });
286
+ });
287
+ });
288
+ }
226
289
  hydrateOrderPaymentNames(payments) {
227
290
  if (!payments.length)
228
291
  return [];
@@ -637,9 +700,13 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
637
700
  );
638
701
  }
639
702
  await this.getPaymentMethodsAsync();
703
+ this.registerServerOrderChangeSync();
640
704
  this.core.effects.emit(`${this.name}:onInited`, {});
641
705
  }
642
706
  async destroy() {
707
+ var _a;
708
+ (_a = this.serverOrderChangeUnsubscribe) == null ? void 0 : _a.call(this);
709
+ this.serverOrderChangeUnsubscribe = null;
643
710
  Object.keys(this.store).forEach((key) => {
644
711
  if (this.reusedSharedSubModuleNames.has(key))
645
712
  return;
@@ -666,30 +733,35 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
666
733
  async loadSalesDetail(orderIdOrParams) {
667
734
  if (!this.store.order)
668
735
  throw new Error("order 模块未初始化");
669
- const params = typeof orderIdOrParams === "object" ? orderIdOrParams : { orderId: orderIdOrParams };
670
- const externalSaleNumber = params.externalSaleNumber || params.external_sale_number;
671
- const preloadedSalesDetail = params.preloadedSalesDetail;
672
- const lookup = params.orderId ?? externalSaleNumber ?? params.orderNumber ?? (preloadedSalesDetail == null ? void 0 : preloadedSalesDetail.order_id) ?? (preloadedSalesDetail == null ? void 0 : preloadedSalesDetail.external_sale_number) ?? (preloadedSalesDetail == null ? void 0 : preloadedSalesDetail.order_number);
673
- if (!preloadedSalesDetail && (lookup === void 0 || lookup === null || lookup === "")) {
674
- throw new Error("加载销售详情需要 orderIdexternalSaleNumber orderNumber");
675
- }
676
- const loadedRecord = preloadedSalesDetail ?? await this.store.order.getSalesOrderByLookup({
677
- lookup,
678
- forceRemote: params.forceRemote
679
- });
680
- if (!preloadedSalesDetail && (!loadedRecord || loadedRecord.code !== 200)) {
681
- const message = loadedRecord && (loadedRecord.message || loadedRecord.msg) || `加载销售详情失败: ${lookup}`;
682
- throw new Error(message);
683
- }
684
- const remoteRecord = preloadedSalesDetail ?? loadedRecord.data;
685
- const currentTempOrder = params.merge ? this.store.order.getTempOrder() : null;
686
- const record = params.merge ? mergeSalesDetailRecordWithTempOrder(currentTempOrder, remoteRecord) : remoteRecord;
687
- const sales = await this.store.order.hydrateTempOrderFromRecord(record, {
688
- recalcOnHydrate: false
689
- });
690
- this.currentSalesDetail = sales;
691
- await this.core.effects.emit(`${this.name}:onSalesOrderLoaded`, { sales });
692
- return sales;
736
+ this.salesDetailLoadInFlight = true;
737
+ try {
738
+ const params = typeof orderIdOrParams === "object" ? orderIdOrParams : { orderId: orderIdOrParams };
739
+ const externalSaleNumber = params.externalSaleNumber || params.external_sale_number;
740
+ const preloadedSalesDetail = params.preloadedSalesDetail;
741
+ const lookup = params.orderId ?? externalSaleNumber ?? params.orderNumber ?? (preloadedSalesDetail == null ? void 0 : preloadedSalesDetail.order_id) ?? (preloadedSalesDetail == null ? void 0 : preloadedSalesDetail.external_sale_number) ?? (preloadedSalesDetail == null ? void 0 : preloadedSalesDetail.order_number);
742
+ if (!preloadedSalesDetail && (lookup === void 0 || lookup === null || lookup === "")) {
743
+ throw new Error("加载销售详情需要 orderId、externalSaleNumber orderNumber");
744
+ }
745
+ const loadedRecord = preloadedSalesDetail ?? await this.store.order.getSalesOrderByLookup({
746
+ lookup,
747
+ forceRemote: params.forceRemote
748
+ });
749
+ if (!preloadedSalesDetail && (!loadedRecord || loadedRecord.code !== 200)) {
750
+ const message = loadedRecord && (loadedRecord.message || loadedRecord.msg) || `加载销售详情失败: ${lookup}`;
751
+ throw new Error(message);
752
+ }
753
+ const remoteRecord = preloadedSalesDetail ?? loadedRecord.data;
754
+ const currentTempOrder = params.merge ? this.store.order.getTempOrder() : null;
755
+ const record = params.merge ? mergeSalesDetailRecordWithTempOrder(currentTempOrder, remoteRecord) : remoteRecord;
756
+ const sales = await this.store.order.hydrateTempOrderFromRecord(record, {
757
+ recalcOnHydrate: false
758
+ });
759
+ this.currentSalesDetail = sales;
760
+ await this.core.effects.emit(`${this.name}:onSalesOrderLoaded`, { sales });
761
+ return sales;
762
+ } finally {
763
+ this.salesDetailLoadInFlight = false;
764
+ }
693
765
  }
694
766
  /** 获取当前已加载的销售详情(只读快照)。未加载过则返回 null。 */
695
767
  getSalesOrder() {
@@ -1696,15 +1768,17 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1696
1768
  return this.store.order.discardPendingVoucherPayments();
1697
1769
  }
1698
1770
  getWalletProductList() {
1699
- var _a, _b, _c;
1771
+ var _a, _b;
1700
1772
  const tempOrder = (_a = this.store.order) == null ? void 0 : _a.getTempOrder();
1701
1773
  if (!((_b = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _b.length))
1702
1774
  return [];
1703
- const products = (_c = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _c.filter((n) => n.product_id);
1704
- const walletProducts = products.map((product) => {
1775
+ const walletProducts = tempOrder == null ? void 0 : tempOrder.products.map((product) => {
1705
1776
  const metadata = product.metadata || {};
1777
+ const rawHolderId = product.holder_id ?? metadata.holder_id;
1778
+ const holderIdValue = Array.isArray(rawHolderId) ? rawHolderId[0] : rawHolderId;
1779
+ const holder_id = Number.isInteger(Number(holderIdValue)) ? Number(holderIdValue) : void 0;
1706
1780
  return {
1707
- product_id: product.product_id,
1781
+ product_id: product.product_id || 0,
1708
1782
  product_variant_id: String(product.product_variant_id ?? ""),
1709
1783
  quantity: product.num || 1,
1710
1784
  is_price_include_tax: tempOrder.is_price_include_tax,
@@ -1712,7 +1786,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1712
1786
  tax_fee: product.tax_fee,
1713
1787
  selling_price: Number(product.selling_price || 0),
1714
1788
  discount_list: product.discount_list || [],
1715
- holder_id: product.holder_id ?? metadata.holder_id,
1789
+ holder_id,
1716
1790
  original_price: product.original_price,
1717
1791
  main_product_original_price: metadata.main_product_original_price ?? product.original_price,
1718
1792
  main_product_selling_price: metadata.main_product_selling_price ?? product.selling_price,
@@ -88,7 +88,8 @@ function normalizeBundleItems(bundleItems, preferPriceField = false) {
88
88
  price: bundleItem.price ?? unitStr,
89
89
  bundle_selling_price: unitStr,
90
90
  original_price: bundleItem.original_price ?? bundleItem.product_price ?? bundleItem.price ?? unitStr,
91
- option: normalizeOptionItems(bundleItem == null ? void 0 : bundleItem.option)
91
+ option: normalizeOptionItems(bundleItem == null ? void 0 : bundleItem.option),
92
+ discount_list: preferPriceField ? [] : bundleItem.discount_list
92
93
  };
93
94
  normalizedItem.bundle_selling_price = (0, import_utils.getBundleSellingMagnitude)(magnitudeSource).toFixed(2);
94
95
  if ((normalizedItem.price_type ?? normalizedItem.custom_price_type) === "markdown" && (normalizedItem.price_type_ext === "" || normalizedItem.price_type_ext === void 0 || normalizedItem.price_type_ext === null)) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.3.17",
4
+ "version": "2.3.19",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",