@pisell/pisellos 2.3.65 → 2.3.67
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.
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.js +109 -65
- package/dist/model/strategy/adapter/walletPass/evaluator.js +1 -0
- package/dist/model/strategy/adapter/walletPass/utils.js +2 -0
- package/dist/modules/Customer/index.d.ts +0 -4
- package/dist/modules/Customer/index.js +59 -91
- package/dist/modules/Customer/types.d.ts +0 -2
- package/dist/modules/Payment/walletpass.js +5 -4
- package/dist/modules/Quotation/index.d.ts +6 -0
- package/dist/modules/Quotation/index.js +75 -19
- package/dist/plugins/request.d.ts +1 -0
- package/dist/server/index.d.ts +8 -2
- package/dist/server/index.js +209 -142
- package/dist/server/modules/floor-plan/index.d.ts +4 -0
- package/dist/server/modules/floor-plan/index.js +240 -98
- package/dist/server/modules/menu/index.js +48 -23
- package/dist/server/modules/order/index.d.ts +17 -8
- package/dist/server/modules/order/index.js +506 -453
- package/dist/server/modules/products/index.d.ts +8 -2
- package/dist/server/modules/products/index.js +167 -75
- package/dist/server/modules/resource/index.js +21 -13
- package/dist/server/utils/small-ticket.js +1 -2
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +0 -2
- package/dist/solution/BookingTicket/index.js +10 -34
- package/lib/core/index.d.ts +7 -0
- package/lib/core/index.js +20 -2
- package/lib/model/strategy/adapter/promotion/index.js +0 -51
- package/lib/model/strategy/adapter/walletPass/evaluator.js +1 -0
- package/lib/model/strategy/adapter/walletPass/utils.js +1 -0
- package/lib/modules/Customer/index.d.ts +0 -4
- package/lib/modules/Customer/index.js +0 -11
- package/lib/modules/Customer/types.d.ts +0 -2
- package/lib/modules/Payment/walletpass.js +1 -0
- package/lib/modules/Quotation/index.d.ts +6 -0
- package/lib/modules/Quotation/index.js +49 -5
- package/lib/plugins/request.d.ts +1 -0
- package/lib/server/index.d.ts +8 -2
- package/lib/server/index.js +55 -19
- package/lib/server/modules/floor-plan/index.d.ts +4 -0
- package/lib/server/modules/floor-plan/index.js +54 -6
- package/lib/server/modules/menu/index.js +31 -5
- package/lib/server/modules/order/index.d.ts +17 -8
- package/lib/server/modules/order/index.js +199 -106
- package/lib/server/modules/products/index.d.ts +8 -2
- package/lib/server/modules/products/index.js +97 -24
- package/lib/server/modules/resource/index.js +7 -2
- package/lib/server/utils/small-ticket.js +1 -1
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +0 -2
- package/lib/solution/BookingTicket/index.js +2 -18
- package/package.json +1 -1
|
@@ -39,8 +39,8 @@ var import_orderCollectionIdentity = require("../../../modules/Order/utils/order
|
|
|
39
39
|
var import_types = require("./types");
|
|
40
40
|
var import_payment_utils = require("../../../modules/Order/payment-utils");
|
|
41
41
|
var INDEXDB_STORE_NAME = "orders";
|
|
42
|
-
var ORDER_STORAGE_KEY_FIELD = "__order_storage_key";
|
|
43
42
|
var ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY = "server_order_last_full_fetch_at";
|
|
43
|
+
var ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY = "server_order_last_full_fetch_shop_id";
|
|
44
44
|
var ORDER_SYNC_THROTTLE_MS_STORAGE_KEY = "order_sync_throttle_ms";
|
|
45
45
|
var DEFAULT_ORDER_SYNC_THROTTLE_MS = 2e3;
|
|
46
46
|
var ORDER_SQLITE_DEDUPE_MS = 15e3;
|
|
@@ -192,18 +192,21 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
192
192
|
* 仅记录计数与订单标识,不输出商品、预约、支付或客户明细。
|
|
193
193
|
*/
|
|
194
194
|
normalizeOrderCollectionsForIngress(order, source) {
|
|
195
|
-
const
|
|
196
|
-
|
|
195
|
+
const sourceOrderRecord = order;
|
|
196
|
+
let sourceOrder = sourceOrderRecord;
|
|
197
197
|
if (Array.isArray(sourceOrderRecord.payments)) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
198
|
+
sourceOrder = {
|
|
199
|
+
...sourceOrderRecord,
|
|
200
|
+
payments: sourceOrderRecord.payments.map((payment) => {
|
|
201
|
+
if (!(0, import_payment_utils.isPendingOrderPayment)(payment) || (0, import_payment_utils.getOrderPaymentIdentityKeys)(payment).some((key) => key.startsWith("unique_payment_number:"))) {
|
|
202
|
+
return payment;
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
...payment,
|
|
206
|
+
[PENDING_PAYMENT_WITHOUT_UNIQUE_MARKER]: true
|
|
207
|
+
};
|
|
208
|
+
})
|
|
209
|
+
};
|
|
207
210
|
}
|
|
208
211
|
const result = (0, import_orderCollectionIdentity.normalizeOrderCollections)(sourceOrder);
|
|
209
212
|
const normalizedOrderRecord = result.order;
|
|
@@ -525,11 +528,65 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
525
528
|
return DEFAULT_ORDER_SYNC_THROTTLE_MS;
|
|
526
529
|
}
|
|
527
530
|
async preload() {
|
|
528
|
-
const
|
|
531
|
+
const preloadStartedAt = Date.now();
|
|
532
|
+
let cachedOrders = null;
|
|
533
|
+
let sqliteLoadTimings;
|
|
534
|
+
if (this.dbManager) {
|
|
535
|
+
try {
|
|
536
|
+
cachedOrders = await this.loadOrdersFromSQLite({
|
|
537
|
+
throwOnError: true,
|
|
538
|
+
onTiming: (timings) => {
|
|
539
|
+
sqliteLoadTimings = timings;
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
} catch (error) {
|
|
543
|
+
this.logWarning("preload-SQLite读取失败,回退远端全量拉取", {
|
|
544
|
+
error: error instanceof Error ? error.message : String(error)
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
if (cachedOrders !== null && this.hasPulledOrdersToday()) {
|
|
549
|
+
const memoryPrepareStartedAt = performance.now();
|
|
550
|
+
const memoryOrders = this.prepareNormalizedOrdersForMemoryList(cachedOrders);
|
|
551
|
+
const memoryPrepareMs = +(performance.now() - memoryPrepareStartedAt).toFixed(2);
|
|
552
|
+
this.store.list = memoryOrders;
|
|
553
|
+
const syncMapStartedAt = performance.now();
|
|
554
|
+
this.syncOrdersMap();
|
|
555
|
+
const syncMapMs = +(performance.now() - syncMapStartedAt).toFixed(2);
|
|
556
|
+
const onOrdersLoadedStartedAt = performance.now();
|
|
557
|
+
await this.core.effects.emit(import_types.OrderHooks.onOrdersLoaded, this.store.list);
|
|
558
|
+
const onOrdersLoadedMs = +(performance.now() - onOrdersLoadedStartedAt).toFixed(2);
|
|
559
|
+
const emitOrdersChangedStartedAt = performance.now();
|
|
560
|
+
await this.emitOrdersChanged([], "preload.sqlite");
|
|
561
|
+
const emitOrdersChangedMs = +(performance.now() - emitOrdersChangedStartedAt).toFixed(2);
|
|
562
|
+
this.logInfo("预加载完成", {
|
|
563
|
+
trigger: "preload",
|
|
564
|
+
source: "SQLite",
|
|
565
|
+
orderCount: this.store.list.length,
|
|
566
|
+
duration: `${Date.now() - preloadStartedAt}ms`,
|
|
567
|
+
stages: {
|
|
568
|
+
...sqliteLoadTimings || {},
|
|
569
|
+
memoryPrepareMs,
|
|
570
|
+
syncMapMs,
|
|
571
|
+
onOrdersLoadedMs,
|
|
572
|
+
emitOrdersChangedMs
|
|
573
|
+
}
|
|
574
|
+
});
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
const orders = await this.loadOrdersByServer({
|
|
578
|
+
trigger: "preload"
|
|
579
|
+
});
|
|
529
580
|
this.store.list = (0, import_lodash_es.cloneDeep)(orders);
|
|
530
581
|
this.syncOrdersMap();
|
|
531
582
|
await this.emitOrdersChanged([], "preload");
|
|
532
583
|
await this.core.effects.emit(import_types.OrderHooks.onOrdersSyncCompleted, null);
|
|
584
|
+
this.logInfo("预加载完成", {
|
|
585
|
+
trigger: "preload",
|
|
586
|
+
source: "Server",
|
|
587
|
+
orderCount: this.store.list.length,
|
|
588
|
+
duration: `${Date.now() - preloadStartedAt}ms`
|
|
589
|
+
});
|
|
533
590
|
}
|
|
534
591
|
getOrders() {
|
|
535
592
|
return this.store.list;
|
|
@@ -750,13 +807,16 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
750
807
|
this.logInfo("updateLocalPayment-变更事件完成", paymentContext);
|
|
751
808
|
return { order: nextOrder, payment: nextPayment, previousPayment };
|
|
752
809
|
}
|
|
753
|
-
async loadOrdersByServer() {
|
|
810
|
+
async loadOrdersByServer(options = {}) {
|
|
754
811
|
var _a;
|
|
755
812
|
let orderList = [];
|
|
813
|
+
let hasFetchedRemoteSnapshot = false;
|
|
814
|
+
const trigger = options.trigger || "unknown";
|
|
756
815
|
const protectedOrdersBeforeRemoteFetch = (await this.loadOrdersFromSQLite()).filter(
|
|
757
816
|
(order) => this.shouldProtectLocalOrderFromRemoteSnapshot(order)
|
|
758
817
|
);
|
|
759
818
|
this.logInfo("loadOrdersByServer-开始", {
|
|
819
|
+
trigger,
|
|
760
820
|
hasOrderDataSource: !!this.orderDataSource,
|
|
761
821
|
query: ((_a = this.store) == null ? void 0 : _a.createdAtQuery) || null,
|
|
762
822
|
protectedLocalOrderCount: protectedOrdersBeforeRemoteFetch.length,
|
|
@@ -774,25 +834,36 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
774
834
|
});
|
|
775
835
|
orderList = data || [];
|
|
776
836
|
this.logInfo("loadOrdersByServer-SSE拉取成功", {
|
|
837
|
+
trigger,
|
|
777
838
|
count: orderList.length
|
|
778
839
|
});
|
|
779
|
-
|
|
840
|
+
hasFetchedRemoteSnapshot = true;
|
|
780
841
|
this.lastServerFullFetchAtMs = Date.now();
|
|
781
842
|
} catch {
|
|
782
843
|
this.logInfo("loadOrdersByServer-SSE拉取失败,保持当前内存订单");
|
|
783
844
|
return this.store.list;
|
|
784
845
|
}
|
|
785
846
|
}
|
|
786
|
-
|
|
847
|
+
if (hasFetchedRemoteSnapshot) {
|
|
848
|
+
this.clearOrderSnapshotMarker();
|
|
849
|
+
}
|
|
850
|
+
const {
|
|
851
|
+
orders: mergedOrders,
|
|
852
|
+
persisted: isRemoteSnapshotPersisted
|
|
853
|
+
} = await this.replaceOrdersSnapshotInSQLite(
|
|
787
854
|
orderList,
|
|
788
855
|
"loadOrdersByServer",
|
|
789
856
|
protectedOrdersBeforeRemoteFetch
|
|
790
857
|
);
|
|
858
|
+
if (hasFetchedRemoteSnapshot && isRemoteSnapshotPersisted) {
|
|
859
|
+
this.markOrderPulledAtNow();
|
|
860
|
+
}
|
|
791
861
|
const memoryOrders = this.normalizeOrdersForMemoryList(
|
|
792
862
|
mergedOrders,
|
|
793
863
|
"loadOrdersByServer.memory"
|
|
794
864
|
);
|
|
795
865
|
this.logInfo("loadOrdersByServer-结束", {
|
|
866
|
+
trigger,
|
|
796
867
|
count: memoryOrders.length,
|
|
797
868
|
persistedCount: mergedOrders.length,
|
|
798
869
|
sqliteOnlyDraftCount: mergedOrders.length - memoryOrders.length
|
|
@@ -805,21 +876,34 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
805
876
|
* 拿到完整数据后一次性替换 store,触发订单变更与同步完成事件
|
|
806
877
|
* @returns 刷新后的订单列表
|
|
807
878
|
*/
|
|
808
|
-
async silentRefresh() {
|
|
879
|
+
async silentRefresh(options = {}) {
|
|
809
880
|
const startTime = Date.now();
|
|
881
|
+
const trigger = options.trigger || "background";
|
|
810
882
|
const elapsedSinceFullFetch = Date.now() - this.lastServerFullFetchAtMs;
|
|
811
883
|
if (this.lastServerFullFetchAtMs > 0 && elapsedSinceFullFetch < ORDER_SILENT_REFRESH_MIN_INTERVAL_MS) {
|
|
884
|
+
this.logInfo("silentRefresh 跳过全量 SSE", {
|
|
885
|
+
trigger,
|
|
886
|
+
reason: "within_min_interval",
|
|
887
|
+
minIntervalMs: ORDER_SILENT_REFRESH_MIN_INTERVAL_MS,
|
|
888
|
+
elapsedSinceFullFetchMs: elapsedSinceFullFetch,
|
|
889
|
+
orderCount: this.store.list.length
|
|
890
|
+
});
|
|
812
891
|
return this.store.list;
|
|
813
892
|
}
|
|
814
|
-
this.logInfo("silentRefresh 开始"
|
|
893
|
+
this.logInfo("silentRefresh 开始", {
|
|
894
|
+
trigger,
|
|
895
|
+
elapsedSinceFullFetchMs: elapsedSinceFullFetch,
|
|
896
|
+
orderCount: this.store.list.length
|
|
897
|
+
});
|
|
815
898
|
try {
|
|
816
899
|
this.updateCreateStore();
|
|
817
|
-
const orders = await this.loadOrdersByServer();
|
|
900
|
+
const orders = await this.loadOrdersByServer({ trigger });
|
|
818
901
|
this.store.list = (0, import_lodash_es.cloneDeep)(orders);
|
|
819
902
|
this.syncOrdersMap();
|
|
820
903
|
await this.emitOrdersChanged([], "silentRefresh");
|
|
821
904
|
await this.core.effects.emit(import_types.OrderHooks.onOrdersSyncCompleted, null);
|
|
822
905
|
this.logInfo("silentRefresh 完成", {
|
|
906
|
+
trigger,
|
|
823
907
|
orderCount: orders.length,
|
|
824
908
|
duration: `${Date.now() - startTime}ms`
|
|
825
909
|
});
|
|
@@ -827,6 +911,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
827
911
|
} catch (error) {
|
|
828
912
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
829
913
|
this.logError("silentRefresh 失败", {
|
|
914
|
+
trigger,
|
|
830
915
|
duration: `${Date.now() - startTime}ms`,
|
|
831
916
|
error: errorMessage
|
|
832
917
|
});
|
|
@@ -835,6 +920,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
835
920
|
}
|
|
836
921
|
normalizeOrderForMemoryList(order, source = "normalizeOrderForMemoryList") {
|
|
837
922
|
const normalizedOrder = this.normalizeOrderCollectionsForIngress(order, source);
|
|
923
|
+
return this.prepareNormalizedOrderForMemoryList(normalizedOrder);
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* 将已经完成集合规范化的订单转换为内存身份,不重复扫描 products/bookings/payments。
|
|
927
|
+
*/
|
|
928
|
+
prepareNormalizedOrderForMemoryList(normalizedOrder) {
|
|
838
929
|
const externalSaleNumber = normalizedOrder == null ? void 0 : normalizedOrder.external_sale_number;
|
|
839
930
|
if (this.isDraftOrder(normalizedOrder) && !this.hasRealOrderId(normalizedOrder)) {
|
|
840
931
|
return normalizedOrder;
|
|
@@ -850,6 +941,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
850
941
|
order_id: externalSaleNumber
|
|
851
942
|
};
|
|
852
943
|
}
|
|
944
|
+
prepareNormalizedOrdersForMemoryList(orders) {
|
|
945
|
+
return orders.map((order) => this.prepareNormalizedOrderForMemoryList(order)).filter((order) => this.shouldKeepOrderInMemory(order));
|
|
946
|
+
}
|
|
853
947
|
normalizeOrdersForMemoryList(orders, source) {
|
|
854
948
|
return orders.map((order) => this.normalizeOrderForMemoryList(order, source)).filter((order) => this.shouldKeepOrderInMemory(order));
|
|
855
949
|
}
|
|
@@ -1534,7 +1628,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1534
1628
|
const patchedOrders = [];
|
|
1535
1629
|
const remoteProductMembershipChanges = [];
|
|
1536
1630
|
const forceWriteStorageKeys = /* @__PURE__ */ new Set();
|
|
1537
|
-
const storageKeyMigrations = [];
|
|
1538
1631
|
const mergeActions = {};
|
|
1539
1632
|
const existingProductsHaveStableIdentity = this.store.list.map(
|
|
1540
1633
|
(order) => this.doProductsHaveStableMembershipIdentity(
|
|
@@ -1559,7 +1652,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1559
1652
|
const mergeKey = storageKey || (fresh.order_id !== void 0 && fresh.order_id !== null ? this.getIdKey(fresh.order_id) : "");
|
|
1560
1653
|
if (matchIndex >= 0) {
|
|
1561
1654
|
const existingOrder = updatedList[matchIndex];
|
|
1562
|
-
const previousStorageKey = this.getPersistedOrderStorageKey(existingOrder);
|
|
1563
1655
|
if (this.isPendingSyncOrder(existingOrder) && this.isRemoteEchoMergeSource(source)) {
|
|
1564
1656
|
this.logInfo("mergeOrdersToStore-跳过 pending 订单远端覆盖", {
|
|
1565
1657
|
source,
|
|
@@ -1621,14 +1713,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1621
1713
|
}
|
|
1622
1714
|
}
|
|
1623
1715
|
}
|
|
1624
|
-
const nextStorageKey = this.getOrderStorageKey(mergedOrder);
|
|
1625
|
-
if (previousStorageKey && nextStorageKey && previousStorageKey !== nextStorageKey) {
|
|
1626
|
-
storageKeyMigrations.push({
|
|
1627
|
-
orderId: mergedOrder.order_id ?? existingOrder.order_id ?? fresh.order_id ?? null,
|
|
1628
|
-
from: previousStorageKey,
|
|
1629
|
-
to: nextStorageKey
|
|
1630
|
-
});
|
|
1631
|
-
}
|
|
1632
1716
|
updatedList[adjustedMatchIndex] = mergedOrder;
|
|
1633
1717
|
existingProductsHaveStableIdentity[adjustedMatchIndex] = mergedProductsHaveStableIdentity;
|
|
1634
1718
|
if (membershipChange) {
|
|
@@ -1666,7 +1750,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1666
1750
|
patchedOrders,
|
|
1667
1751
|
source,
|
|
1668
1752
|
mergeActions,
|
|
1669
|
-
{
|
|
1753
|
+
{},
|
|
1670
1754
|
forceWriteStorageKeys
|
|
1671
1755
|
);
|
|
1672
1756
|
this.logInfo("mergeOrdersToStore-结束", {
|
|
@@ -1871,13 +1955,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1871
1955
|
}
|
|
1872
1956
|
return "";
|
|
1873
1957
|
}
|
|
1874
|
-
getPersistedOrderStorageKey(order) {
|
|
1875
|
-
const persistedStorageKey = order == null ? void 0 : order[ORDER_STORAGE_KEY_FIELD];
|
|
1876
|
-
if (persistedStorageKey !== void 0 && persistedStorageKey !== null && persistedStorageKey !== "") {
|
|
1877
|
-
return String(persistedStorageKey);
|
|
1878
|
-
}
|
|
1879
|
-
return this.getOrderStorageKey(order);
|
|
1880
|
-
}
|
|
1881
1958
|
getOrderIdentityMatchKeys(order) {
|
|
1882
1959
|
return this.getOrderIdentityEntries(order).map((entry) => `${entry.field}:${entry.key}`);
|
|
1883
1960
|
}
|
|
@@ -2137,20 +2214,29 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
2137
2214
|
return { list, removedCount };
|
|
2138
2215
|
}
|
|
2139
2216
|
/**
|
|
2140
|
-
*
|
|
2141
|
-
*
|
|
2142
|
-
* - 无法解析时退化为自然日窗口
|
|
2217
|
+
* 当前订单缓存可复用窗口。
|
|
2218
|
+
* start_time 模式使用精确的营业日起止时间;配置缺失或异常时退化为自然日。
|
|
2143
2219
|
*/
|
|
2144
|
-
|
|
2145
|
-
var _a
|
|
2220
|
+
getCurrentOrderCacheWindow() {
|
|
2221
|
+
var _a;
|
|
2146
2222
|
const now = (0, import_dayjs.default)();
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
const
|
|
2150
|
-
const
|
|
2151
|
-
|
|
2152
|
-
|
|
2223
|
+
try {
|
|
2224
|
+
const appPlugin = this.core.getPlugin("app");
|
|
2225
|
+
const app = appPlugin == null ? void 0 : appPlugin.getApp();
|
|
2226
|
+
const coreData = app == null ? void 0 : app.data.store.getStore().getDataByModel("core");
|
|
2227
|
+
const boundary = (_a = coreData == null ? void 0 : coreData.core) == null ? void 0 : _a.operating_day_boundary;
|
|
2228
|
+
if ((boundary == null ? void 0 : boundary.type) === "start_time") {
|
|
2229
|
+
const boundaryTime = String(boundary.time || "").trim();
|
|
2230
|
+
const todayBoundary = (0, import_dayjs.default)(`${now.format("YYYY-MM-DD")} ${boundaryTime}`);
|
|
2231
|
+
if (todayBoundary.isValid()) {
|
|
2232
|
+
const startAt2 = now.isBefore(todayBoundary) ? todayBoundary.subtract(1, "day") : todayBoundary;
|
|
2233
|
+
return {
|
|
2234
|
+
startAt: startAt2,
|
|
2235
|
+
endExclusiveAt: startAt2.add(1, "day")
|
|
2236
|
+
};
|
|
2237
|
+
}
|
|
2153
2238
|
}
|
|
2239
|
+
} catch {
|
|
2154
2240
|
}
|
|
2155
2241
|
const startAt = now.startOf("day");
|
|
2156
2242
|
return { startAt, endExclusiveAt: startAt.add(1, "day") };
|
|
@@ -2159,17 +2245,51 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
2159
2245
|
const lastFullFetchAt = this.getStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY);
|
|
2160
2246
|
if (!lastFullFetchAt)
|
|
2161
2247
|
return false;
|
|
2248
|
+
const currentShopId = this.getCurrentShopId();
|
|
2249
|
+
const lastFullFetchShopId = this.getStorageItem(
|
|
2250
|
+
ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY
|
|
2251
|
+
);
|
|
2252
|
+
if (!currentShopId || !lastFullFetchShopId || currentShopId !== lastFullFetchShopId) {
|
|
2253
|
+
return false;
|
|
2254
|
+
}
|
|
2162
2255
|
const parsed = (0, import_dayjs.default)(lastFullFetchAt);
|
|
2163
2256
|
if (!parsed.isValid())
|
|
2164
2257
|
return false;
|
|
2165
|
-
const { startAt, endExclusiveAt } = this.
|
|
2258
|
+
const { startAt, endExclusiveAt } = this.getCurrentOrderCacheWindow();
|
|
2166
2259
|
return (parsed.isAfter(startAt) || parsed.isSame(startAt)) && parsed.isBefore(endExclusiveAt);
|
|
2167
2260
|
}
|
|
2168
2261
|
markOrderPulledAtNow() {
|
|
2262
|
+
const currentShopId = this.getCurrentShopId();
|
|
2263
|
+
if (!currentShopId)
|
|
2264
|
+
return;
|
|
2169
2265
|
this.setStorageItem(
|
|
2170
2266
|
ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY,
|
|
2171
2267
|
(0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
|
|
2172
2268
|
);
|
|
2269
|
+
this.setStorageItem(
|
|
2270
|
+
ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY,
|
|
2271
|
+
currentShopId
|
|
2272
|
+
);
|
|
2273
|
+
}
|
|
2274
|
+
clearOrderSnapshotMarker() {
|
|
2275
|
+
this.setStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY, "");
|
|
2276
|
+
this.setStorageItem(ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY, "");
|
|
2277
|
+
}
|
|
2278
|
+
getCurrentShopId() {
|
|
2279
|
+
var _a;
|
|
2280
|
+
try {
|
|
2281
|
+
const appPlugin = this.core.getPlugin("app");
|
|
2282
|
+
const app = appPlugin == null ? void 0 : appPlugin.getApp();
|
|
2283
|
+
if (!app)
|
|
2284
|
+
return null;
|
|
2285
|
+
const coreData = app.data.store.getStore().getDataByModel("core");
|
|
2286
|
+
const shopId = (_a = coreData == null ? void 0 : coreData.core) == null ? void 0 : _a.id;
|
|
2287
|
+
if (shopId === void 0 || shopId === null || shopId === "")
|
|
2288
|
+
return null;
|
|
2289
|
+
return String(shopId);
|
|
2290
|
+
} catch {
|
|
2291
|
+
return null;
|
|
2292
|
+
}
|
|
2173
2293
|
}
|
|
2174
2294
|
getStorageItem(key) {
|
|
2175
2295
|
var _a;
|
|
@@ -2196,15 +2316,29 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
2196
2316
|
} catch {
|
|
2197
2317
|
}
|
|
2198
2318
|
}
|
|
2199
|
-
async loadOrdersFromSQLite() {
|
|
2319
|
+
async loadOrdersFromSQLite(options = {}) {
|
|
2320
|
+
var _a;
|
|
2200
2321
|
if (!this.dbManager)
|
|
2201
2322
|
return [];
|
|
2202
2323
|
try {
|
|
2324
|
+
const loadStartedAt = performance.now();
|
|
2325
|
+
const rawReadStartedAt = performance.now();
|
|
2203
2326
|
const orders = await this.dbManager.getAll(INDEXDB_STORE_NAME);
|
|
2204
|
-
|
|
2327
|
+
const sqliteRawReadMs = +(performance.now() - rawReadStartedAt).toFixed(2);
|
|
2328
|
+
const normalizeStartedAt = performance.now();
|
|
2329
|
+
const normalizedOrders = (orders || []).map(
|
|
2205
2330
|
(order) => this.normalizeOrderCollectionsForIngress(order, "loadOrdersFromSQLite")
|
|
2206
2331
|
);
|
|
2207
|
-
|
|
2332
|
+
const sqliteNormalizeMs = +(performance.now() - normalizeStartedAt).toFixed(2);
|
|
2333
|
+
(_a = options.onTiming) == null ? void 0 : _a.call(options, {
|
|
2334
|
+
sqliteRawReadMs,
|
|
2335
|
+
sqliteNormalizeMs,
|
|
2336
|
+
sqliteLoadTotalMs: +(performance.now() - loadStartedAt).toFixed(2)
|
|
2337
|
+
});
|
|
2338
|
+
return normalizedOrders;
|
|
2339
|
+
} catch (error) {
|
|
2340
|
+
if (options.throwOnError)
|
|
2341
|
+
throw error;
|
|
2208
2342
|
return [];
|
|
2209
2343
|
}
|
|
2210
2344
|
}
|
|
@@ -2308,18 +2442,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
2308
2442
|
throw new Error("订单 SQLite 数据库未初始化");
|
|
2309
2443
|
return;
|
|
2310
2444
|
}
|
|
2311
|
-
const
|
|
2312
|
-
(options.storageKeyMigrations || []).map((migration) => migration.to)
|
|
2313
|
-
);
|
|
2314
|
-
const ordersSnapshot = (0, import_lodash_es.cloneDeep)(orders).map((order) => this.normalizeOrderCollectionsForIngress(order, `${source}.sqliteIngress`)).map((order) => {
|
|
2315
|
-
const storageKey = this.getOrderStorageKey(order);
|
|
2316
|
-
if (!storageKey || !migrationTargetStorageKeys.has(storageKey))
|
|
2317
|
-
return order;
|
|
2318
|
-
return {
|
|
2319
|
-
...order,
|
|
2320
|
-
[ORDER_STORAGE_KEY_FIELD]: storageKey
|
|
2321
|
-
};
|
|
2322
|
-
}).filter((order) => this.getOrderStorageKey(order));
|
|
2445
|
+
const ordersSnapshot = (0, import_lodash_es.cloneDeep)(orders).map((order) => this.normalizeOrderCollectionsForIngress(order, `${source}.sqliteIngress`)).filter((order) => this.getOrderStorageKey(order));
|
|
2323
2446
|
if (ordersSnapshot.length === 0) {
|
|
2324
2447
|
return;
|
|
2325
2448
|
}
|
|
@@ -2336,17 +2459,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
2336
2459
|
if (compactedToWrite.length === 0) {
|
|
2337
2460
|
return;
|
|
2338
2461
|
}
|
|
2339
|
-
const writtenStorageKeys = new Set(
|
|
2340
|
-
compactedToWrite.map((order) => this.getOrderStorageKey(order)).filter(Boolean)
|
|
2341
|
-
);
|
|
2342
|
-
const storageKeyMigrations = /* @__PURE__ */ new Map();
|
|
2343
|
-
for (const migration of options.storageKeyMigrations || []) {
|
|
2344
|
-
if (!writtenStorageKeys.has(migration.to))
|
|
2345
|
-
continue;
|
|
2346
|
-
if (writtenStorageKeys.has(migration.from))
|
|
2347
|
-
continue;
|
|
2348
|
-
storageKeyMigrations.set(migration.from, migration);
|
|
2349
|
-
}
|
|
2350
2462
|
try {
|
|
2351
2463
|
await this.runInOrderSQLiteSaveQueue(async () => {
|
|
2352
2464
|
let writeMethod = "none";
|
|
@@ -2370,30 +2482,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
2370
2482
|
throw new Error("订单 SQLite 数据库不支持写入");
|
|
2371
2483
|
}
|
|
2372
2484
|
this.recordRecentSqliteWrite(source, compactedToWrite);
|
|
2373
|
-
if (writeMethod !== "none") {
|
|
2374
|
-
for (const migration of storageKeyMigrations.values()) {
|
|
2375
|
-
try {
|
|
2376
|
-
await this.dbManager.delete(INDEXDB_STORE_NAME, migration.from);
|
|
2377
|
-
this.recentSqliteWriteByStorageKey.delete(migration.from);
|
|
2378
|
-
for (const order of orders) {
|
|
2379
|
-
if (this.getOrderStorageKey(order) !== migration.to)
|
|
2380
|
-
continue;
|
|
2381
|
-
const orderRecord = order;
|
|
2382
|
-
if (String(orderRecord[ORDER_STORAGE_KEY_FIELD] ?? "") !== migration.from)
|
|
2383
|
-
continue;
|
|
2384
|
-
orderRecord[ORDER_STORAGE_KEY_FIELD] = migration.to;
|
|
2385
|
-
}
|
|
2386
|
-
} catch (error) {
|
|
2387
|
-
this.logError("删除订单旧 SQLite storage key 失败", {
|
|
2388
|
-
source,
|
|
2389
|
-
order_id: migration.orderId,
|
|
2390
|
-
oldStorageKey: migration.from,
|
|
2391
|
-
newStorageKey: migration.to,
|
|
2392
|
-
error: error instanceof Error ? error.message : String(error)
|
|
2393
|
-
});
|
|
2394
|
-
}
|
|
2395
|
-
}
|
|
2396
|
-
}
|
|
2397
2485
|
this.logInfo("patchOrdersInSQLite-完成", {
|
|
2398
2486
|
source,
|
|
2399
2487
|
count: compactedToWrite.length,
|
|
@@ -2472,14 +2560,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
2472
2560
|
* 用于 SSE 全量拉取与营业日窗口裁剪。
|
|
2473
2561
|
*
|
|
2474
2562
|
* @example
|
|
2475
|
-
* await this.replaceOrdersSnapshotInSQLite(orderList)
|
|
2563
|
+
* const { orders, persisted } = await this.replaceOrdersSnapshotInSQLite(orderList, 'refresh')
|
|
2476
2564
|
*/
|
|
2477
2565
|
async replaceOrdersSnapshotInSQLite(orderList, source, protectedOrdersBeforeRemoteFetch = []) {
|
|
2478
2566
|
if (!this.dbManager) {
|
|
2479
|
-
return
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2567
|
+
return {
|
|
2568
|
+
orders: this.compactOrderListByIdentity(
|
|
2569
|
+
orderList.map((order) => this.normalizeRemoteSyncedOrder(order)),
|
|
2570
|
+
`${source}.snapshotNoDb`
|
|
2571
|
+
).list,
|
|
2572
|
+
persisted: false
|
|
2573
|
+
};
|
|
2483
2574
|
}
|
|
2484
2575
|
const remoteSnapshot = (0, import_lodash_es.cloneDeep)(orderList).map(
|
|
2485
2576
|
(order) => this.normalizeOrderCollectionsForIngress(order, `${source}.remoteIngress`)
|
|
@@ -2488,6 +2579,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
2488
2579
|
remoteSnapshot.map((order) => this.normalizeRemoteSyncedOrder(order)),
|
|
2489
2580
|
`${source}.remoteSnapshot`
|
|
2490
2581
|
).list;
|
|
2582
|
+
let persisted = false;
|
|
2491
2583
|
try {
|
|
2492
2584
|
await this.runInOrderSQLiteSaveQueue(async () => {
|
|
2493
2585
|
const existingOrders = typeof this.dbManager.getAll === "function" ? await this.dbManager.getAll(INDEXDB_STORE_NAME) : [];
|
|
@@ -2552,13 +2644,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
2552
2644
|
count: mergedSnapshot.length
|
|
2553
2645
|
});
|
|
2554
2646
|
});
|
|
2647
|
+
persisted = true;
|
|
2555
2648
|
} catch (error) {
|
|
2556
2649
|
this.logError("全量保存订单到 SQLite 失败", {
|
|
2557
2650
|
error: error instanceof Error ? error.message : String(error),
|
|
2558
2651
|
orderList: remoteSnapshot.length
|
|
2559
2652
|
});
|
|
2560
2653
|
}
|
|
2561
|
-
return mergedSnapshot;
|
|
2654
|
+
return { orders: mergedSnapshot, persisted };
|
|
2562
2655
|
}
|
|
2563
2656
|
/**
|
|
2564
2657
|
* 清空订单模块的内存数据和本地 SQLite 订单表。
|
|
@@ -2574,7 +2667,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
2574
2667
|
await this.dbManager.clear(INDEXDB_STORE_NAME);
|
|
2575
2668
|
});
|
|
2576
2669
|
}
|
|
2577
|
-
this.
|
|
2670
|
+
this.clearOrderSnapshotMarker();
|
|
2578
2671
|
this.emitOrdersChanged([], "clear");
|
|
2579
2672
|
}
|
|
2580
2673
|
};
|
|
@@ -25,6 +25,7 @@ export declare class ProductsModule extends BaseModule implements Module {
|
|
|
25
25
|
private quotationBridgeLoadedKey?;
|
|
26
26
|
private quotationBridgeRefreshPromise?;
|
|
27
27
|
private quotationBridgeRefreshKey?;
|
|
28
|
+
private quotationBridgeUpdatedCallback?;
|
|
28
29
|
private quotationScheduleCache;
|
|
29
30
|
private quotationScheduleCacheSource;
|
|
30
31
|
private quotationScheduleCacheLoaded;
|
|
@@ -72,6 +73,7 @@ export declare class ProductsModule extends BaseModule implements Module {
|
|
|
72
73
|
scheduleModule?: any;
|
|
73
74
|
channel?: string;
|
|
74
75
|
customer_id?: number | string;
|
|
76
|
+
onQuotationUpdated?: () => void;
|
|
75
77
|
}): Promise<void>;
|
|
76
78
|
/**
|
|
77
79
|
* 刷新桥接器内的报价单列表。
|
|
@@ -181,7 +183,9 @@ export declare class ProductsModule extends BaseModule implements Module {
|
|
|
181
183
|
/**
|
|
182
184
|
* 通过 ProductDataSource SSE 加载完整商品列表
|
|
183
185
|
*/
|
|
184
|
-
loadProductsByServer(
|
|
186
|
+
loadProductsByServer(options?: {
|
|
187
|
+
trigger?: string;
|
|
188
|
+
}): Promise<any>;
|
|
185
189
|
/**
|
|
186
190
|
* 纯请求方法:通过 HTTP 接口获取商品列表(无副作用,不触发事件、不写 IndexDB)
|
|
187
191
|
* @param params 查询参数
|
|
@@ -331,7 +335,9 @@ export declare class ProductsModule extends BaseModule implements Module {
|
|
|
331
335
|
* 拿到完整数据后一次性替换 store,清除价格缓存,触发 onProductsSyncCompleted
|
|
332
336
|
* @returns 刷新后的商品列表
|
|
333
337
|
*/
|
|
334
|
-
silentRefresh(
|
|
338
|
+
silentRefresh(options?: {
|
|
339
|
+
trigger?: string;
|
|
340
|
+
}): Promise<ProductData[]>;
|
|
335
341
|
/**
|
|
336
342
|
* 销毁同步资源(取消 pubsub 订阅、清除定时器)
|
|
337
343
|
*/
|