@pisell/pisellos 2.3.2 → 2.3.3
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/model/strategy/adapter/promotion/index.js +9 -0
- package/dist/modules/Order/index.js +0 -2
- package/dist/server/index.js +0 -1
- package/dist/server/modules/order/index.d.ts +25 -7
- package/dist/server/modules/order/index.js +370 -309
- package/lib/modules/Order/index.js +0 -2
- package/lib/server/modules/order/index.d.ts +25 -7
- package/lib/server/modules/order/index.js +88 -54
- package/package.json +1 -1
|
@@ -3892,8 +3892,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
3892
3892
|
async getOrderInfo(order_id) {
|
|
3893
3893
|
const res = await this.request.get(`/order/sales/${order_id}`, {
|
|
3894
3894
|
with: ["products", "bookings"]
|
|
3895
|
-
}, {
|
|
3896
|
-
osServer: true
|
|
3897
3895
|
});
|
|
3898
3896
|
return res;
|
|
3899
3897
|
}
|
|
@@ -15,7 +15,6 @@ export declare class OrderModule extends BaseModule implements Module {
|
|
|
15
15
|
private syncTimer?;
|
|
16
16
|
private isProcessingSyncBatch;
|
|
17
17
|
private isIdlePhase;
|
|
18
|
-
private resourceIdIndex;
|
|
19
18
|
private logger;
|
|
20
19
|
private storage;
|
|
21
20
|
private orderSQLiteSaveQueue; /** 按 storageKey 记录最近一次 SQLite 写入来源与时间,用于去重 */
|
|
@@ -32,10 +31,10 @@ export declare class OrderModule extends BaseModule implements Module {
|
|
|
32
31
|
private emitOrdersChanged;
|
|
33
32
|
initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
|
|
34
33
|
/**
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
* 记录信息日志
|
|
35
|
+
* @param title 日志标题
|
|
36
|
+
* @param metadata 日志元数据
|
|
37
|
+
*/
|
|
39
38
|
private logInfo;
|
|
40
39
|
/**
|
|
41
40
|
* 记录错误日志
|
|
@@ -89,7 +88,6 @@ export declare class OrderModule extends BaseModule implements Module {
|
|
|
89
88
|
* @returns 刷新后的订单列表
|
|
90
89
|
*/
|
|
91
90
|
silentRefresh(): Promise<OrderData[]>;
|
|
92
|
-
getOrdersByResourceId(resourceId: string | number): OrderData[];
|
|
93
91
|
private normalizeOrderForMemoryList;
|
|
94
92
|
/**
|
|
95
93
|
* 仅覆盖本地已存在的订单;不存在则直接跳过,不落库、不 emit。
|
|
@@ -126,7 +124,6 @@ export declare class OrderModule extends BaseModule implements Module {
|
|
|
126
124
|
private isBlankIdentityValue;
|
|
127
125
|
private getOrderIdentityEntries;
|
|
128
126
|
private getOrderIdentityKeys;
|
|
129
|
-
private extractResourceIds;
|
|
130
127
|
private getOrderDateKey;
|
|
131
128
|
/**
|
|
132
129
|
* 初始化 OrderDataSource 实例
|
|
@@ -175,6 +172,27 @@ export declare class OrderModule extends BaseModule implements Module {
|
|
|
175
172
|
* 将增量订单合并到 store
|
|
176
173
|
*/
|
|
177
174
|
private mergeOrdersToStore;
|
|
175
|
+
/**
|
|
176
|
+
* 在身份索引中查找与目标订单共享任一身份键的已存在订单下标。
|
|
177
|
+
* 返回所有命中键里最小的下标,等价于原 findOrderIndexByIdentity 的「取首个匹配」语义。
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* const idx = this.lookupOrderIndexByIdentityKeys(identityKeyToIndex, freshIdentityKeys)
|
|
181
|
+
*/
|
|
182
|
+
private lookupOrderIndexByIdentityKeys;
|
|
183
|
+
/**
|
|
184
|
+
* 将订单的全部身份键登记到索引并指向其在列表中的下标。
|
|
185
|
+
* 合并后订单新增的身份字段(如挂单同步后拿到 order_id)也会被登记。
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* this.registerOrderIdentityKeys(identityKeyToIndex, mergedOrder, matchIndex)
|
|
189
|
+
*/
|
|
190
|
+
private registerOrderIdentityKeys;
|
|
191
|
+
/**
|
|
192
|
+
* 合并热路径去重兜底:默认直接返回原列表(增量索引已保证无重复)。
|
|
193
|
+
* 仅当 ORDER_MERGE_SELF_CHECK 开启时,额外做一次全表压缩并在发现残留重复时告警。
|
|
194
|
+
*/
|
|
195
|
+
private runOrderStoreSelfCheck;
|
|
178
196
|
private normalizeOrderSyncMessage;
|
|
179
197
|
private normalizeOrderSyncPayload;
|
|
180
198
|
private uniqueOrderIds;
|
|
@@ -48,6 +48,7 @@ var ORDER_BUSINESS_WRITE_SOURCES = /* @__PURE__ */ new Set([
|
|
|
48
48
|
"overwriteExistingOrder",
|
|
49
49
|
"markOrderSyncedByExternalSaleNumber"
|
|
50
50
|
]);
|
|
51
|
+
var ORDER_MERGE_SELF_CHECK = false;
|
|
51
52
|
var OrderModule = class extends import_BaseModule.BaseModule {
|
|
52
53
|
constructor(name, version) {
|
|
53
54
|
super(name, version);
|
|
@@ -56,8 +57,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
56
57
|
this.pendingSyncMessages = [];
|
|
57
58
|
this.isProcessingSyncBatch = false;
|
|
58
59
|
this.isIdlePhase = true;
|
|
59
|
-
// Map<resource_id, OrderId[]> 资源到订单的倒排索引
|
|
60
|
-
this.resourceIdIndex = /* @__PURE__ */ new Map();
|
|
61
60
|
this.orderSQLiteSaveQueue = Promise.resolve();
|
|
62
61
|
/** 按 storageKey 记录最近一次 SQLite 写入来源与时间,用于去重 */
|
|
63
62
|
this.recentSqliteWriteByStorageKey = /* @__PURE__ */ new Map();
|
|
@@ -110,10 +109,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
110
109
|
});
|
|
111
110
|
}
|
|
112
111
|
/**
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
112
|
+
* 记录信息日志
|
|
113
|
+
* @param title 日志标题
|
|
114
|
+
* @param metadata 日志元数据
|
|
115
|
+
*/
|
|
117
116
|
logInfo(title, metadata) {
|
|
118
117
|
try {
|
|
119
118
|
if (this.logger) {
|
|
@@ -481,10 +480,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
481
480
|
return this.store.list;
|
|
482
481
|
}
|
|
483
482
|
}
|
|
484
|
-
getOrdersByResourceId(resourceId) {
|
|
485
|
-
const ids = this.resourceIdIndex.get(String(resourceId)) || [];
|
|
486
|
-
return ids.map((id) => this.store.map.get(id)).filter((order) => !!order);
|
|
487
|
-
}
|
|
488
483
|
normalizeOrderForMemoryList(order) {
|
|
489
484
|
const externalSaleNumber = order == null ? void 0 : order.external_sale_number;
|
|
490
485
|
if ((order == null ? void 0 : order.order_id) !== void 0 && (order == null ? void 0 : order.order_id) !== null && (order == null ? void 0 : order.order_id) !== "") {
|
|
@@ -617,22 +612,33 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
617
612
|
const patchedOrders = [...pendingMap.values()];
|
|
618
613
|
const mergeActions = {};
|
|
619
614
|
const updatedList = [...this.store.list];
|
|
615
|
+
const identityKeyToIndex = /* @__PURE__ */ new Map();
|
|
616
|
+
for (let index = 0; index < updatedList.length; index += 1) {
|
|
617
|
+
for (const key of this.getOrderIdentityMatchKeys(updatedList[index])) {
|
|
618
|
+
if (!identityKeyToIndex.has(key))
|
|
619
|
+
identityKeyToIndex.set(key, index);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
620
622
|
for (const [storageKey, pendingOrder] of memoryPendingMap.entries()) {
|
|
621
|
-
const matchIndex = this.
|
|
622
|
-
|
|
623
|
+
const matchIndex = this.lookupOrderIndexByIdentityKeys(
|
|
624
|
+
identityKeyToIndex,
|
|
625
|
+
this.getOrderIdentityMatchKeys(pendingOrder)
|
|
626
|
+
);
|
|
627
|
+
if (matchIndex >= 0) {
|
|
628
|
+
const mergedOrder = this.mergeOrderRecords(updatedList[matchIndex], pendingOrder, {
|
|
629
|
+
preferIncomingProducts: true
|
|
630
|
+
});
|
|
631
|
+
updatedList[matchIndex] = mergedOrder;
|
|
632
|
+
this.registerOrderIdentityKeys(identityKeyToIndex, mergedOrder, matchIndex);
|
|
633
|
+
mergeActions[storageKey] = "update";
|
|
623
634
|
continue;
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
memoryPendingMap.delete(storageKey);
|
|
629
|
-
mergeActions[storageKey] = "update";
|
|
630
|
-
}
|
|
631
|
-
for (const [storageKey, order] of memoryPendingMap.entries()) {
|
|
635
|
+
}
|
|
636
|
+
const insertIndex = updatedList.length;
|
|
637
|
+
updatedList.push(pendingOrder);
|
|
638
|
+
this.registerOrderIdentityKeys(identityKeyToIndex, pendingOrder, insertIndex);
|
|
632
639
|
mergeActions[storageKey] = "insert";
|
|
633
|
-
updatedList.push(order);
|
|
634
640
|
}
|
|
635
|
-
this.store.list = this.
|
|
641
|
+
this.store.list = this.runOrderStoreSelfCheck(updatedList, "upsertPendingSyncOrders.store");
|
|
636
642
|
this.syncOrdersMap();
|
|
637
643
|
await this.patchOrdersInSQLite(patchedOrders, "upsertPendingSyncOrders", mergeActions);
|
|
638
644
|
this.logInfo("upsertPendingSyncOrders-结束", {
|
|
@@ -674,21 +680,11 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
674
680
|
}
|
|
675
681
|
syncOrdersMap() {
|
|
676
682
|
this.store.map.clear();
|
|
677
|
-
this.resourceIdIndex.clear();
|
|
678
683
|
for (const order of this.store.list) {
|
|
679
684
|
const primaryIdentity = this.getOrderMapKey(order);
|
|
680
685
|
if (!primaryIdentity)
|
|
681
686
|
continue;
|
|
682
687
|
this.store.map.set(primaryIdentity, order);
|
|
683
|
-
const resourceIds = this.extractResourceIds(order);
|
|
684
|
-
for (const resourceId of resourceIds) {
|
|
685
|
-
const key = String(resourceId);
|
|
686
|
-
const existing = this.resourceIdIndex.get(key) || [];
|
|
687
|
-
if (existing.some((eid) => this.getIdKey(eid) === primaryIdentity))
|
|
688
|
-
continue;
|
|
689
|
-
existing.push(primaryIdentity);
|
|
690
|
-
this.resourceIdIndex.set(key, existing);
|
|
691
|
-
}
|
|
692
688
|
}
|
|
693
689
|
}
|
|
694
690
|
getOrderMapKey(order) {
|
|
@@ -735,24 +731,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
735
731
|
}
|
|
736
732
|
return keys;
|
|
737
733
|
}
|
|
738
|
-
extractResourceIds(order) {
|
|
739
|
-
const ids = /* @__PURE__ */ new Set();
|
|
740
|
-
const visitResources = (resources) => {
|
|
741
|
-
if (!Array.isArray(resources))
|
|
742
|
-
return;
|
|
743
|
-
resources.forEach((resource) => {
|
|
744
|
-
const rid = resource == null ? void 0 : resource.relation_id;
|
|
745
|
-
if (rid !== void 0 && rid !== null && rid !== "")
|
|
746
|
-
ids.add(String(rid));
|
|
747
|
-
if (Array.isArray(resource == null ? void 0 : resource.children))
|
|
748
|
-
visitResources(resource.children);
|
|
749
|
-
});
|
|
750
|
-
};
|
|
751
|
-
if (Array.isArray(order == null ? void 0 : order.bookings)) {
|
|
752
|
-
order.bookings.forEach((booking) => visitResources((booking == null ? void 0 : booking.resources) || []));
|
|
753
|
-
}
|
|
754
|
-
return [...ids];
|
|
755
|
-
}
|
|
756
734
|
getOrderDateKey(order) {
|
|
757
735
|
var _a, _b, _c, _d;
|
|
758
736
|
const candidates = [
|
|
@@ -971,9 +949,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
971
949
|
* 将增量订单合并到 store
|
|
972
950
|
*/
|
|
973
951
|
async mergeOrdersToStore(freshOrders, source) {
|
|
952
|
+
const storeOrderCountBefore = this.store.list.length;
|
|
974
953
|
this.logInfo("mergeOrdersToStore-开始", {
|
|
975
954
|
freshOrderCount: freshOrders.length,
|
|
976
|
-
storeOrderCountBefore
|
|
955
|
+
storeOrderCountBefore,
|
|
977
956
|
source
|
|
978
957
|
});
|
|
979
958
|
this.logDuplicateOrders(`${source}.beforeMerge`, this.store.list);
|
|
@@ -992,19 +971,31 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
992
971
|
const patchedOrders = [];
|
|
993
972
|
const mergeActions = {};
|
|
994
973
|
const updatedList = [...this.store.list];
|
|
974
|
+
const identityKeyToIndex = /* @__PURE__ */ new Map();
|
|
975
|
+
for (let index = 0; index < updatedList.length; index += 1) {
|
|
976
|
+
const identityKeys = this.getOrderIdentityMatchKeys(updatedList[index]);
|
|
977
|
+
for (const key of identityKeys) {
|
|
978
|
+
if (!identityKeyToIndex.has(key))
|
|
979
|
+
identityKeyToIndex.set(key, index);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
995
982
|
for (const fresh of uniqueFreshOrders) {
|
|
996
|
-
const
|
|
983
|
+
const freshIdentityKeys = this.getOrderIdentityMatchKeys(fresh);
|
|
984
|
+
const matchIndex = this.lookupOrderIndexByIdentityKeys(identityKeyToIndex, freshIdentityKeys);
|
|
997
985
|
const storageKey = this.getOrderStorageKey(fresh);
|
|
998
986
|
const mergeKey = storageKey || (fresh.order_id !== void 0 && fresh.order_id !== null ? this.getIdKey(fresh.order_id) : "");
|
|
999
987
|
if (matchIndex >= 0) {
|
|
1000
988
|
const mergedOrder = this.mergeOrderRecords(updatedList[matchIndex], fresh);
|
|
1001
989
|
updatedList[matchIndex] = mergedOrder;
|
|
990
|
+
this.registerOrderIdentityKeys(identityKeyToIndex, mergedOrder, matchIndex);
|
|
1002
991
|
patchedOrders.push(mergedOrder);
|
|
1003
992
|
if (mergeKey)
|
|
1004
993
|
mergeActions[mergeKey] = "update";
|
|
1005
994
|
continue;
|
|
1006
995
|
}
|
|
996
|
+
const insertIndex = updatedList.length;
|
|
1007
997
|
updatedList.push(fresh);
|
|
998
|
+
this.registerOrderIdentityKeys(identityKeyToIndex, fresh, insertIndex);
|
|
1008
999
|
patchedOrders.push(fresh);
|
|
1009
1000
|
if (mergeKey)
|
|
1010
1001
|
mergeActions[mergeKey] = "insert";
|
|
@@ -1016,7 +1007,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1016
1007
|
updateCount,
|
|
1017
1008
|
storeOrderCountAfter: this.store.list.length
|
|
1018
1009
|
});
|
|
1019
|
-
this.store.list = this.
|
|
1010
|
+
this.store.list = this.runOrderStoreSelfCheck(updatedList, `${source}.store`);
|
|
1020
1011
|
this.syncOrdersMap();
|
|
1021
1012
|
await this.patchOrdersInSQLite(patchedOrders, source, mergeActions);
|
|
1022
1013
|
this.logInfo("mergeOrdersToStore-结束", {
|
|
@@ -1027,6 +1018,50 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1027
1018
|
});
|
|
1028
1019
|
await this.emitOrdersChanged(patchedOrders, source);
|
|
1029
1020
|
}
|
|
1021
|
+
/**
|
|
1022
|
+
* 在身份索引中查找与目标订单共享任一身份键的已存在订单下标。
|
|
1023
|
+
* 返回所有命中键里最小的下标,等价于原 findOrderIndexByIdentity 的「取首个匹配」语义。
|
|
1024
|
+
*
|
|
1025
|
+
* @example
|
|
1026
|
+
* const idx = this.lookupOrderIndexByIdentityKeys(identityKeyToIndex, freshIdentityKeys)
|
|
1027
|
+
*/
|
|
1028
|
+
lookupOrderIndexByIdentityKeys(identityKeyToIndex, identityKeys) {
|
|
1029
|
+
let matchIndex = -1;
|
|
1030
|
+
for (const key of identityKeys) {
|
|
1031
|
+
const index = identityKeyToIndex.get(key);
|
|
1032
|
+
if (index === void 0)
|
|
1033
|
+
continue;
|
|
1034
|
+
if (matchIndex < 0 || index < matchIndex)
|
|
1035
|
+
matchIndex = index;
|
|
1036
|
+
}
|
|
1037
|
+
return matchIndex;
|
|
1038
|
+
}
|
|
1039
|
+
/**
|
|
1040
|
+
* 将订单的全部身份键登记到索引并指向其在列表中的下标。
|
|
1041
|
+
* 合并后订单新增的身份字段(如挂单同步后拿到 order_id)也会被登记。
|
|
1042
|
+
*
|
|
1043
|
+
* @example
|
|
1044
|
+
* this.registerOrderIdentityKeys(identityKeyToIndex, mergedOrder, matchIndex)
|
|
1045
|
+
*/
|
|
1046
|
+
registerOrderIdentityKeys(identityKeyToIndex, order, index) {
|
|
1047
|
+
const identityKeys = this.getOrderIdentityMatchKeys(order);
|
|
1048
|
+
for (const key of identityKeys) {
|
|
1049
|
+
identityKeyToIndex.set(key, index);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* 合并热路径去重兜底:默认直接返回原列表(增量索引已保证无重复)。
|
|
1054
|
+
* 仅当 ORDER_MERGE_SELF_CHECK 开启时,额外做一次全表压缩并在发现残留重复时告警。
|
|
1055
|
+
*/
|
|
1056
|
+
runOrderStoreSelfCheck(orders, source) {
|
|
1057
|
+
if (!ORDER_MERGE_SELF_CHECK)
|
|
1058
|
+
return orders;
|
|
1059
|
+
const { list, removedCount } = this.compactOrderListByIdentity(orders, source);
|
|
1060
|
+
if (removedCount > 0) {
|
|
1061
|
+
this.logWarning("合并自检发现残留重复订单,已压缩", { source, removedCount });
|
|
1062
|
+
}
|
|
1063
|
+
return list;
|
|
1064
|
+
}
|
|
1030
1065
|
normalizeOrderSyncMessage(res) {
|
|
1031
1066
|
const data = (res == null ? void 0 : res.data) || res;
|
|
1032
1067
|
if (!data)
|
|
@@ -1640,7 +1675,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1640
1675
|
async clear() {
|
|
1641
1676
|
this.store.list = [];
|
|
1642
1677
|
this.store.map = /* @__PURE__ */ new Map();
|
|
1643
|
-
this.resourceIdIndex.clear();
|
|
1644
1678
|
if (this.dbManager) {
|
|
1645
1679
|
await this.runInOrderSQLiteSaveQueue(async () => {
|
|
1646
1680
|
await this.dbManager.clear(INDEXDB_STORE_NAME);
|