@pisell/pisellos 2.3.28 → 2.3.29
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/dataVariant/adapter.d.ts +50 -0
- package/dist/model/strategy/adapter/dataVariant/adapter.js +167 -0
- package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +89 -0
- package/dist/model/strategy/adapter/dataVariant/evaluator.js +780 -0
- package/dist/model/strategy/adapter/dataVariant/examples.d.ts +39 -0
- package/dist/model/strategy/adapter/dataVariant/examples.js +277 -0
- package/dist/model/strategy/adapter/dataVariant/index.d.ts +4 -0
- package/dist/model/strategy/adapter/dataVariant/index.js +4 -0
- package/dist/model/strategy/adapter/dataVariant/type.d.ts +148 -0
- package/dist/model/strategy/adapter/dataVariant/type.js +54 -0
- package/dist/model/strategy/adapter/index.d.ts +4 -0
- package/dist/model/strategy/adapter/index.js +5 -1
- package/dist/model/strategy/adapter/promotion/index.js +0 -9
- package/dist/modules/Discount/index.d.ts +5 -2
- package/dist/modules/Discount/index.js +30 -7
- package/dist/modules/Discount/types.d.ts +4 -0
- package/dist/modules/Order/index.d.ts +7 -1
- package/dist/modules/Order/index.js +187 -74
- package/dist/modules/Order/types.d.ts +2 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.js +405 -0
- package/dist/modules/Order/utils.d.ts +2 -1
- package/dist/modules/Order/utils.js +2 -8
- package/dist/modules/Product/types.d.ts +22 -0
- package/dist/modules/ProductList/index.d.ts +1 -1
- package/dist/modules/ProductList/index.js +4 -2
- package/dist/modules/ProductList/types.d.ts +2 -0
- package/dist/server/index.d.ts +50 -0
- package/dist/server/index.js +995 -749
- package/dist/server/modules/order/index.d.ts +10 -4
- package/dist/server/modules/order/index.js +404 -399
- package/dist/server/modules/products/index.d.ts +26 -7
- package/dist/server/modules/products/index.js +167 -76
- package/dist/server/modules/products/types.d.ts +14 -0
- package/dist/solution/BaseSales/index.d.ts +9 -1
- package/dist/solution/BaseSales/index.js +998 -756
- package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -3
- package/dist/solution/BaseSales/utils/parseSalesResponse.js +6 -8
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +14 -2
- package/dist/solution/BookingTicket/types.d.ts +2 -0
- package/dist/solution/ShopDiscount/index.js +15 -14
- package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +50 -0
- package/lib/model/strategy/adapter/dataVariant/adapter.js +149 -0
- package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +89 -0
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +583 -0
- package/lib/model/strategy/adapter/dataVariant/examples.d.ts +39 -0
- package/lib/model/strategy/adapter/dataVariant/examples.js +293 -0
- package/lib/model/strategy/adapter/dataVariant/index.d.ts +4 -0
- package/lib/model/strategy/adapter/dataVariant/index.js +38 -0
- package/lib/model/strategy/adapter/dataVariant/type.d.ts +148 -0
- package/lib/model/strategy/adapter/dataVariant/type.js +31 -0
- package/lib/model/strategy/adapter/index.d.ts +4 -0
- package/lib/model/strategy/adapter/index.js +13 -2
- package/lib/modules/Discount/index.d.ts +5 -2
- package/lib/modules/Discount/index.js +23 -3
- package/lib/modules/Discount/types.d.ts +4 -0
- package/lib/modules/Order/index.d.ts +7 -1
- package/lib/modules/Order/index.js +104 -6
- package/lib/modules/Order/types.d.ts +2 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.js +415 -0
- package/lib/modules/Order/utils.d.ts +2 -1
- package/lib/modules/Order/utils.js +4 -11
- package/lib/modules/Product/types.d.ts +22 -0
- package/lib/modules/ProductList/index.d.ts +1 -1
- package/lib/modules/ProductList/index.js +4 -2
- package/lib/modules/ProductList/types.d.ts +2 -0
- package/lib/server/index.d.ts +50 -0
- package/lib/server/index.js +206 -29
- package/lib/server/modules/order/index.d.ts +10 -4
- package/lib/server/modules/order/index.js +198 -139
- package/lib/server/modules/products/index.d.ts +26 -7
- package/lib/server/modules/products/index.js +114 -35
- package/lib/server/modules/products/types.d.ts +14 -0
- package/lib/solution/BaseSales/index.d.ts +9 -1
- package/lib/solution/BaseSales/index.js +229 -54
- package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -3
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +4 -5
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +14 -2
- package/lib/solution/BookingTicket/types.d.ts +2 -0
- package/lib/solution/ShopDiscount/index.js +2 -1
- package/package.json +1 -1
|
@@ -35,6 +35,7 @@ module.exports = __toCommonJS(order_exports);
|
|
|
35
35
|
var import_lodash_es = require("lodash-es");
|
|
36
36
|
var import_dayjs = __toESM(require("dayjs"));
|
|
37
37
|
var import_BaseModule = require("../../../modules/BaseModule");
|
|
38
|
+
var import_orderCollectionIdentity = require("../../../modules/Order/utils/orderCollectionIdentity");
|
|
38
39
|
var import_types = require("./types");
|
|
39
40
|
var INDEXDB_STORE_NAME = "orders";
|
|
40
41
|
var ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY = "server_order_last_full_fetch_at";
|
|
@@ -49,6 +50,12 @@ var ORDER_BUSINESS_WRITE_SOURCES = /* @__PURE__ */ new Set([
|
|
|
49
50
|
"markOrderSyncedByExternalSaleNumber"
|
|
50
51
|
]);
|
|
51
52
|
var ORDER_MERGE_SELF_CHECK = false;
|
|
53
|
+
var ORDER_AUTHORITATIVE_COLLECTION_FIELDS = ["products", "bookings", "payments"];
|
|
54
|
+
var ORDER_COLLECTION_KIND_BY_FIELD = {
|
|
55
|
+
products: "product",
|
|
56
|
+
bookings: "booking",
|
|
57
|
+
payments: "payment"
|
|
58
|
+
};
|
|
52
59
|
var OrderModule = class extends import_BaseModule.BaseModule {
|
|
53
60
|
constructor(name, version) {
|
|
54
61
|
super(name, version);
|
|
@@ -154,6 +161,96 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
154
161
|
} catch {
|
|
155
162
|
}
|
|
156
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* 在订单进入内存或 SQLite 前统一压缩子项强身份重复并补齐协议 UID。
|
|
166
|
+
* 仅记录计数与订单标识,不输出商品、预约、支付或客户明细。
|
|
167
|
+
*/
|
|
168
|
+
normalizeOrderCollectionsForIngress(order, source) {
|
|
169
|
+
const result = (0, import_orderCollectionIdentity.normalizeOrderCollections)(order);
|
|
170
|
+
const kinds = ["product", "booking", "payment"];
|
|
171
|
+
const hasChanges = kinds.some((kind) => {
|
|
172
|
+
const stats = result.stats[kind];
|
|
173
|
+
return stats.backfilledUidCount > 0 || stats.collapsedDuplicateCount > 0 || stats.uidConflictCount > 0 || stats.anonymousRowCount > 0;
|
|
174
|
+
});
|
|
175
|
+
if (hasChanges) {
|
|
176
|
+
const summarize = (stats) => ({
|
|
177
|
+
backfilled_uid_count: stats.backfilledUidCount,
|
|
178
|
+
collapsed_duplicate_count: stats.collapsedDuplicateCount,
|
|
179
|
+
uid_conflict_count: stats.uidConflictCount,
|
|
180
|
+
anonymous_row_count: stats.anonymousRowCount
|
|
181
|
+
});
|
|
182
|
+
const context = {
|
|
183
|
+
source,
|
|
184
|
+
order_id: (order == null ? void 0 : order.order_id) ?? null,
|
|
185
|
+
external_sale_number: (order == null ? void 0 : order.external_sale_number) ?? null,
|
|
186
|
+
products: summarize(result.stats.product),
|
|
187
|
+
bookings: summarize(result.stats.booking),
|
|
188
|
+
payments: summarize(result.stats.payment)
|
|
189
|
+
};
|
|
190
|
+
const hasUnsafeIdentity = kinds.some((kind) => {
|
|
191
|
+
const stats = result.stats[kind];
|
|
192
|
+
return stats.uidConflictCount > 0 || stats.anonymousRowCount > 0;
|
|
193
|
+
});
|
|
194
|
+
if (hasUnsafeIdentity) {
|
|
195
|
+
this.logWarning("订单子项身份存在冲突或匿名行", context);
|
|
196
|
+
} else {
|
|
197
|
+
this.logInfo("订单子项身份已规范化", context);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return result.order;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* incoming 决定权威成员集合;同一持久化行仍从 existing 补齐 incoming 省略的本地展示字段。
|
|
204
|
+
*/
|
|
205
|
+
mergeAuthoritativeOrderCollection(field, existing, incoming, uidRemaps = []) {
|
|
206
|
+
const kind = ORDER_COLLECTION_KIND_BY_FIELD[field];
|
|
207
|
+
const existingItems = Array.isArray(existing) ? existing : [];
|
|
208
|
+
return incoming.map((incomingItem) => {
|
|
209
|
+
const existingItem = existingItems.find(
|
|
210
|
+
(item) => (0, import_orderCollectionIdentity.isSameOrderCollectionItem)(kind, item, incomingItem)
|
|
211
|
+
);
|
|
212
|
+
if (!existingItem)
|
|
213
|
+
return (0, import_lodash_es.cloneDeep)(incomingItem);
|
|
214
|
+
const mergedItem = (0, import_orderCollectionIdentity.mergeOrderCollectionItems)(kind, existingItem, incomingItem);
|
|
215
|
+
const mergedUid = (0, import_orderCollectionIdentity.getOrderCollectionUid)(kind, mergedItem);
|
|
216
|
+
if (mergedUid) {
|
|
217
|
+
for (const from of /* @__PURE__ */ new Set([
|
|
218
|
+
(0, import_orderCollectionIdentity.getOrderCollectionReferenceUid)(kind, existingItem),
|
|
219
|
+
(0, import_orderCollectionIdentity.getOrderCollectionReferenceUid)(kind, incomingItem)
|
|
220
|
+
])) {
|
|
221
|
+
if (!from || from === mergedUid)
|
|
222
|
+
continue;
|
|
223
|
+
uidRemaps.push({
|
|
224
|
+
kind,
|
|
225
|
+
from,
|
|
226
|
+
to: mergedUid,
|
|
227
|
+
persistentId: (0, import_orderCollectionIdentity.getOrderCollectionPersistentId)(kind, incomingItem) || (0, import_orderCollectionIdentity.getOrderCollectionPersistentId)(kind, existingItem)
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return mergedItem;
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
reconcileOverwriteOrderCollections(existing, incoming) {
|
|
235
|
+
const reconciled = (0, import_lodash_es.cloneDeep)(incoming);
|
|
236
|
+
const existingRecord = existing;
|
|
237
|
+
const incomingRecord = incoming;
|
|
238
|
+
const uidRemaps = [];
|
|
239
|
+
for (const field of ORDER_AUTHORITATIVE_COLLECTION_FIELDS) {
|
|
240
|
+
if (!Array.isArray(incomingRecord[field]))
|
|
241
|
+
continue;
|
|
242
|
+
reconciled[field] = this.mergeAuthoritativeOrderCollection(
|
|
243
|
+
field,
|
|
244
|
+
existingRecord[field],
|
|
245
|
+
incomingRecord[field],
|
|
246
|
+
uidRemaps
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
return this.normalizeOrderCollectionsForIngress(
|
|
250
|
+
(0, import_orderCollectionIdentity.applyOrderCollectionUidRemaps)(reconciled, uidRemaps),
|
|
251
|
+
"overwriteExistingOrder.reconciled"
|
|
252
|
+
);
|
|
253
|
+
}
|
|
157
254
|
/**
|
|
158
255
|
* 记录订单最近一次 SQLite 写入,供 pubsub 回声去重使用。
|
|
159
256
|
*
|
|
@@ -479,16 +576,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
479
576
|
return this.store.list;
|
|
480
577
|
}
|
|
481
578
|
}
|
|
482
|
-
normalizeOrderForMemoryList(order) {
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
|
|
579
|
+
normalizeOrderForMemoryList(order, source = "normalizeOrderForMemoryList") {
|
|
580
|
+
const normalizedOrder = this.normalizeOrderCollectionsForIngress(order, source);
|
|
581
|
+
const externalSaleNumber = normalizedOrder == null ? void 0 : normalizedOrder.external_sale_number;
|
|
582
|
+
if ((normalizedOrder == null ? void 0 : normalizedOrder.order_id) !== void 0 && (normalizedOrder == null ? void 0 : normalizedOrder.order_id) !== null && (normalizedOrder == null ? void 0 : normalizedOrder.order_id) !== "") {
|
|
583
|
+
return normalizedOrder;
|
|
486
584
|
}
|
|
487
585
|
if (externalSaleNumber === void 0 || externalSaleNumber === null || externalSaleNumber === "") {
|
|
488
|
-
return
|
|
586
|
+
return normalizedOrder;
|
|
489
587
|
}
|
|
490
588
|
return {
|
|
491
|
-
...
|
|
589
|
+
...normalizedOrder,
|
|
492
590
|
order_id: externalSaleNumber
|
|
493
591
|
};
|
|
494
592
|
}
|
|
@@ -511,19 +609,29 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
511
609
|
orderId,
|
|
512
610
|
storeOrderCountBefore: this.store.list.length
|
|
513
611
|
});
|
|
612
|
+
const normalizedFresh = this.normalizeOrderForMemoryList(
|
|
613
|
+
fresh,
|
|
614
|
+
"overwriteExistingOrder.incoming"
|
|
615
|
+
);
|
|
616
|
+
const existingOrder = this.store.map.get(key);
|
|
617
|
+
const reconciledFresh = this.reconcileOverwriteOrderCollections(
|
|
618
|
+
existingOrder,
|
|
619
|
+
normalizedFresh
|
|
620
|
+
);
|
|
514
621
|
this.store.list = this.store.list.map((order) => {
|
|
515
622
|
const id = order == null ? void 0 : order.order_id;
|
|
516
|
-
if (id === void 0 || id === null)
|
|
517
|
-
return order;
|
|
518
|
-
|
|
623
|
+
if (id === void 0 || id === null) {
|
|
624
|
+
return this.normalizeOrderForMemoryList(order, "overwriteExistingOrder.existingMemory");
|
|
625
|
+
}
|
|
626
|
+
return this.getIdKey(id) === key ? reconciledFresh : this.normalizeOrderForMemoryList(order, "overwriteExistingOrder.existingMemory");
|
|
519
627
|
});
|
|
520
628
|
this.syncOrdersMap();
|
|
521
|
-
await this.updateOrderInSQLite(
|
|
629
|
+
await this.updateOrderInSQLite(reconciledFresh, "overwriteExistingOrder");
|
|
522
630
|
this.logInfo("overwriteExistingOrder-结束", {
|
|
523
631
|
orderId,
|
|
524
632
|
storeOrderCountAfter: this.store.list.length
|
|
525
633
|
});
|
|
526
|
-
await this.emitOrdersChanged([
|
|
634
|
+
await this.emitOrdersChanged([reconciledFresh], "overwriteExistingOrder");
|
|
527
635
|
return { overwritten: true };
|
|
528
636
|
}
|
|
529
637
|
/**
|
|
@@ -595,11 +703,21 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
595
703
|
const pendingMap = /* @__PURE__ */ new Map();
|
|
596
704
|
const memoryPendingMap = /* @__PURE__ */ new Map();
|
|
597
705
|
for (const order of pendingOrders) {
|
|
598
|
-
const
|
|
706
|
+
const normalizedOrder = this.normalizeOrderCollectionsForIngress(
|
|
707
|
+
order,
|
|
708
|
+
"upsertPendingSyncOrders.incoming"
|
|
709
|
+
);
|
|
710
|
+
const storageKey = this.getOrderStorageKey(normalizedOrder);
|
|
599
711
|
if (!storageKey)
|
|
600
712
|
continue;
|
|
601
|
-
pendingMap.set(storageKey,
|
|
602
|
-
memoryPendingMap.set(
|
|
713
|
+
pendingMap.set(storageKey, normalizedOrder);
|
|
714
|
+
memoryPendingMap.set(
|
|
715
|
+
storageKey,
|
|
716
|
+
this.normalizeOrderForMemoryList(
|
|
717
|
+
normalizedOrder,
|
|
718
|
+
"upsertPendingSyncOrders.memory"
|
|
719
|
+
)
|
|
720
|
+
);
|
|
603
721
|
}
|
|
604
722
|
if (pendingMap.size === 0) {
|
|
605
723
|
this.logError("upsertPendingSyncOrders-订单缺少可落库标识", {
|
|
@@ -608,9 +726,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
608
726
|
return;
|
|
609
727
|
}
|
|
610
728
|
this.logInfo("upsertPendingSyncOrders-开始", { count: pendingMap.size });
|
|
611
|
-
const patchedOrders = [...pendingMap.values()];
|
|
612
729
|
const mergeActions = {};
|
|
613
|
-
const updatedList =
|
|
730
|
+
const updatedList = this.store.list.map(
|
|
731
|
+
(order) => this.normalizeOrderForMemoryList(order, "upsertPendingSyncOrders.existingMemory")
|
|
732
|
+
);
|
|
614
733
|
const identityKeyToIndex = /* @__PURE__ */ new Map();
|
|
615
734
|
for (let index = 0; index < updatedList.length; index += 1) {
|
|
616
735
|
for (const key of this.getOrderIdentityMatchKeys(updatedList[index])) {
|
|
@@ -624,10 +743,16 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
624
743
|
this.getOrderIdentityMatchKeys(pendingOrder)
|
|
625
744
|
);
|
|
626
745
|
if (matchIndex >= 0) {
|
|
627
|
-
const
|
|
628
|
-
|
|
629
|
-
});
|
|
746
|
+
const existingOrder = updatedList[matchIndex];
|
|
747
|
+
const mergedOrder = this.mergeOrderRecords(existingOrder, pendingOrder);
|
|
630
748
|
updatedList[matchIndex] = mergedOrder;
|
|
749
|
+
const pendingSnapshot = pendingMap.get(storageKey);
|
|
750
|
+
if (pendingSnapshot) {
|
|
751
|
+
pendingMap.set(
|
|
752
|
+
storageKey,
|
|
753
|
+
this.reconcileOverwriteOrderCollections(existingOrder, pendingSnapshot)
|
|
754
|
+
);
|
|
755
|
+
}
|
|
631
756
|
this.registerOrderIdentityKeys(identityKeyToIndex, mergedOrder, matchIndex);
|
|
632
757
|
mergeActions[storageKey] = "update";
|
|
633
758
|
continue;
|
|
@@ -637,6 +762,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
637
762
|
this.registerOrderIdentityKeys(identityKeyToIndex, pendingOrder, insertIndex);
|
|
638
763
|
mergeActions[storageKey] = "insert";
|
|
639
764
|
}
|
|
765
|
+
const patchedOrders = [...pendingMap.values()];
|
|
640
766
|
this.store.list = this.runOrderStoreSelfCheck(updatedList, "upsertPendingSyncOrders.store");
|
|
641
767
|
this.syncOrdersMap();
|
|
642
768
|
await this.patchOrdersInSQLite(patchedOrders, "upsertPendingSyncOrders", mergeActions);
|
|
@@ -969,7 +1095,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
969
1095
|
const uniqueFreshCount = uniqueFreshOrders.length;
|
|
970
1096
|
const patchedOrders = [];
|
|
971
1097
|
const mergeActions = {};
|
|
972
|
-
const updatedList =
|
|
1098
|
+
const updatedList = this.store.list.map(
|
|
1099
|
+
(order) => this.normalizeOrderForMemoryList(order, `${source}.existingMemory`)
|
|
1100
|
+
);
|
|
973
1101
|
const identityKeyToIndex = /* @__PURE__ */ new Map();
|
|
974
1102
|
for (let index = 0; index < updatedList.length; index += 1) {
|
|
975
1103
|
const identityKeys = this.getOrderIdentityMatchKeys(updatedList[index]);
|
|
@@ -1192,100 +1320,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1192
1320
|
return right;
|
|
1193
1321
|
return left;
|
|
1194
1322
|
}
|
|
1195
|
-
|
|
1196
|
-
var _a;
|
|
1197
|
-
const record = product;
|
|
1198
|
-
if (!record)
|
|
1199
|
-
return [];
|
|
1200
|
-
const keys = [];
|
|
1201
|
-
const metadataUid = (_a = record.metadata) == null ? void 0 : _a.unique_identification_number;
|
|
1202
|
-
if (!this.isBlankIdentityValue(metadataUid))
|
|
1203
|
-
keys.push(`uid:${String(metadataUid)}`);
|
|
1204
|
-
const topLevelUid = record.unique_identification_number;
|
|
1205
|
-
if (!this.isBlankIdentityValue(topLevelUid))
|
|
1206
|
-
keys.push(`uid:${String(topLevelUid)}`);
|
|
1207
|
-
const orderDetailId = record.order_detail_id;
|
|
1208
|
-
if (!this.isBlankIdentityValue(orderDetailId))
|
|
1209
|
-
keys.push(`detail:${String(orderDetailId)}`);
|
|
1210
|
-
const bookingUid = record.booking_uid;
|
|
1211
|
-
if (!this.isBlankIdentityValue(bookingUid))
|
|
1212
|
-
keys.push(`booking:${String(bookingUid)}`);
|
|
1213
|
-
return keys;
|
|
1214
|
-
}
|
|
1215
|
-
mergeOrderProductLists(preferred, secondary) {
|
|
1216
|
-
const preferredList = Array.isArray(preferred) ? preferred : [];
|
|
1217
|
-
const secondaryList = Array.isArray(secondary) ? secondary : [];
|
|
1218
|
-
if (secondaryList.length === 0)
|
|
1219
|
-
return preferredList;
|
|
1220
|
-
if (preferredList.length === 0)
|
|
1221
|
-
return secondaryList;
|
|
1222
|
-
const seenKeys = /* @__PURE__ */ new Set();
|
|
1223
|
-
for (const item of preferredList) {
|
|
1224
|
-
const keys = this.getProductIdentityKeys(item);
|
|
1225
|
-
for (const key of keys)
|
|
1226
|
-
seenKeys.add(key);
|
|
1227
|
-
}
|
|
1228
|
-
const result = [...preferredList];
|
|
1229
|
-
for (const item of secondaryList) {
|
|
1230
|
-
const keys = this.getProductIdentityKeys(item);
|
|
1231
|
-
if (keys.length === 0 || keys.some((key) => seenKeys.has(key)))
|
|
1232
|
-
continue;
|
|
1233
|
-
for (const key of keys)
|
|
1234
|
-
seenKeys.add(key);
|
|
1235
|
-
result.push((0, import_lodash_es.cloneDeep)(item));
|
|
1236
|
-
}
|
|
1237
|
-
return result;
|
|
1238
|
-
}
|
|
1239
|
-
getPaymentMergeKey(payment) {
|
|
1240
|
-
var _a;
|
|
1241
|
-
const record = payment;
|
|
1242
|
-
if (!record)
|
|
1243
|
-
return "";
|
|
1244
|
-
const uniquePaymentNumber = (_a = record.metadata) == null ? void 0 : _a.unique_payment_number;
|
|
1245
|
-
if (!this.isBlankIdentityValue(uniquePaymentNumber)) {
|
|
1246
|
-
return `unique:${String(uniquePaymentNumber)}`;
|
|
1247
|
-
}
|
|
1248
|
-
const orderPaymentId = record.order_payment_id;
|
|
1249
|
-
if (!this.isBlankIdentityValue(orderPaymentId))
|
|
1250
|
-
return `order_payment:${String(orderPaymentId)}`;
|
|
1251
|
-
const code = record.code;
|
|
1252
|
-
const customPaymentId = record.custom_payment_id;
|
|
1253
|
-
if (!this.isBlankIdentityValue(code) && !this.isBlankIdentityValue(customPaymentId)) {
|
|
1254
|
-
return `custom:${String(code)}#${String(customPaymentId)}`;
|
|
1255
|
-
}
|
|
1256
|
-
return "";
|
|
1257
|
-
}
|
|
1258
|
-
mergeOrderPaymentLists(existing, incoming) {
|
|
1259
|
-
const existingList = Array.isArray(existing) ? existing : [];
|
|
1260
|
-
const incomingList = Array.isArray(incoming) ? incoming : [];
|
|
1261
|
-
if (incomingList.length === 0)
|
|
1262
|
-
return (0, import_lodash_es.cloneDeep)(existingList);
|
|
1263
|
-
if (existingList.length === 0)
|
|
1264
|
-
return (0, import_lodash_es.cloneDeep)(incomingList);
|
|
1265
|
-
const existingByKey = /* @__PURE__ */ new Map();
|
|
1266
|
-
for (const payment of existingList) {
|
|
1267
|
-
const key = this.getPaymentMergeKey(payment);
|
|
1268
|
-
if (!key)
|
|
1269
|
-
continue;
|
|
1270
|
-
existingByKey.set(key, payment);
|
|
1271
|
-
}
|
|
1272
|
-
return incomingList.map((payment) => {
|
|
1273
|
-
const incomingPayment = payment;
|
|
1274
|
-
const key = this.getPaymentMergeKey(incomingPayment);
|
|
1275
|
-
const existingPayment = key ? existingByKey.get(key) : void 0;
|
|
1276
|
-
if (!existingPayment)
|
|
1277
|
-
return (0, import_lodash_es.cloneDeep)(incomingPayment);
|
|
1278
|
-
return {
|
|
1279
|
-
...(0, import_lodash_es.cloneDeep)(existingPayment),
|
|
1280
|
-
...(0, import_lodash_es.cloneDeep)(incomingPayment),
|
|
1281
|
-
metadata: {
|
|
1282
|
-
...(0, import_lodash_es.cloneDeep)(existingPayment.metadata || {}),
|
|
1283
|
-
...(0, import_lodash_es.cloneDeep)(incomingPayment.metadata || {})
|
|
1284
|
-
}
|
|
1285
|
-
};
|
|
1286
|
-
});
|
|
1287
|
-
}
|
|
1288
|
-
mergeOrderRecords(existing, incoming, options) {
|
|
1323
|
+
mergeOrderRecords(existing, incoming) {
|
|
1289
1324
|
const preferred = this.pickPreferredOrder(existing, incoming);
|
|
1290
1325
|
const secondary = preferred === existing ? incoming : existing;
|
|
1291
1326
|
const merged = {
|
|
@@ -1306,8 +1341,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1306
1341
|
"updated_at",
|
|
1307
1342
|
"shop_discount",
|
|
1308
1343
|
"summary",
|
|
1309
|
-
"products",
|
|
1310
|
-
"bookings",
|
|
1311
1344
|
"note",
|
|
1312
1345
|
"customer_id",
|
|
1313
1346
|
"customer_name",
|
|
@@ -1321,8 +1354,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1321
1354
|
const mergedRecord = merged;
|
|
1322
1355
|
const preferredRecord = preferred;
|
|
1323
1356
|
const secondaryRecord = secondary;
|
|
1357
|
+
const existingRecord = existing;
|
|
1324
1358
|
const incomingRecord = incoming;
|
|
1325
|
-
const
|
|
1359
|
+
const childUidRemaps = [];
|
|
1326
1360
|
for (const field of fieldsToPreserve) {
|
|
1327
1361
|
if (!this.isBlankIdentityValue(preferredRecord[field])) {
|
|
1328
1362
|
mergedRecord[field] = preferredRecord[field];
|
|
@@ -1332,8 +1366,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1332
1366
|
mergedRecord[field] = secondaryRecord[field];
|
|
1333
1367
|
}
|
|
1334
1368
|
}
|
|
1335
|
-
const hasIncomingProducts = Object.prototype.hasOwnProperty.call(incomingRecord, "products");
|
|
1336
|
-
const shouldUseIncomingProductsSnapshot = (options == null ? void 0 : options.preferIncomingProducts) === true && hasIncomingProducts && incomingRecord.products !== void 0 && incomingRecord.products !== null;
|
|
1337
1369
|
for (const field of incomingPatchFields) {
|
|
1338
1370
|
if (!Object.prototype.hasOwnProperty.call(incomingRecord, field))
|
|
1339
1371
|
continue;
|
|
@@ -1343,21 +1375,29 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1343
1375
|
continue;
|
|
1344
1376
|
mergedRecord[field] = (0, import_lodash_es.cloneDeep)(incomingRecord[field]);
|
|
1345
1377
|
}
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
incomingRecord
|
|
1378
|
+
for (const field of ORDER_AUTHORITATIVE_COLLECTION_FIELDS) {
|
|
1379
|
+
if (Array.isArray(incomingRecord[field])) {
|
|
1380
|
+
mergedRecord[field] = this.mergeAuthoritativeOrderCollection(
|
|
1381
|
+
field,
|
|
1382
|
+
existingRecord[field],
|
|
1383
|
+
incomingRecord[field],
|
|
1384
|
+
childUidRemaps
|
|
1352
1385
|
);
|
|
1353
|
-
|
|
1354
|
-
|
|
1386
|
+
continue;
|
|
1387
|
+
}
|
|
1388
|
+
if (Object.prototype.hasOwnProperty.call(existingRecord, field)) {
|
|
1389
|
+
mergedRecord[field] = (0, import_lodash_es.cloneDeep)(existingRecord[field]);
|
|
1390
|
+
} else {
|
|
1391
|
+
delete mergedRecord[field];
|
|
1355
1392
|
}
|
|
1356
1393
|
}
|
|
1357
1394
|
if (!this.isPendingSyncOrder(preferred) || !this.isPendingSyncOrder(secondary)) {
|
|
1358
1395
|
merged.need_sync = 0;
|
|
1359
1396
|
}
|
|
1360
|
-
return
|
|
1397
|
+
return this.normalizeOrderCollectionsForIngress(
|
|
1398
|
+
(0, import_orderCollectionIdentity.applyOrderCollectionUidRemaps)(merged, childUidRemaps),
|
|
1399
|
+
"mergeOrderRecords"
|
|
1400
|
+
);
|
|
1361
1401
|
}
|
|
1362
1402
|
summarizeDuplicateOrders(orders) {
|
|
1363
1403
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -1394,12 +1434,16 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1394
1434
|
const list = [];
|
|
1395
1435
|
let removedCount = 0;
|
|
1396
1436
|
for (const order of orders) {
|
|
1397
|
-
const
|
|
1437
|
+
const normalizedOrder = this.normalizeOrderCollectionsForIngress(
|
|
1438
|
+
order,
|
|
1439
|
+
`${source}.order`
|
|
1440
|
+
);
|
|
1441
|
+
const matchIndex = this.findOrderIndexByIdentity(list, normalizedOrder);
|
|
1398
1442
|
if (matchIndex < 0) {
|
|
1399
|
-
list.push(
|
|
1443
|
+
list.push(normalizedOrder);
|
|
1400
1444
|
continue;
|
|
1401
1445
|
}
|
|
1402
|
-
list[matchIndex] = this.mergeOrderRecords(list[matchIndex],
|
|
1446
|
+
list[matchIndex] = this.mergeOrderRecords(list[matchIndex], normalizedOrder);
|
|
1403
1447
|
removedCount += 1;
|
|
1404
1448
|
}
|
|
1405
1449
|
if (removedCount > 0) {
|
|
@@ -1479,7 +1523,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1479
1523
|
return [];
|
|
1480
1524
|
try {
|
|
1481
1525
|
const orders = await this.dbManager.getAll(INDEXDB_STORE_NAME);
|
|
1482
|
-
return orders || []
|
|
1526
|
+
return (orders || []).map(
|
|
1527
|
+
(order) => this.normalizeOrderCollectionsForIngress(order, "loadOrdersFromSQLite")
|
|
1528
|
+
);
|
|
1483
1529
|
} catch {
|
|
1484
1530
|
return [];
|
|
1485
1531
|
}
|
|
@@ -1488,16 +1534,24 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1488
1534
|
return Number(order == null ? void 0 : order.need_sync) === 1;
|
|
1489
1535
|
}
|
|
1490
1536
|
normalizeRemoteSyncedOrder(order) {
|
|
1491
|
-
|
|
1492
|
-
|
|
1537
|
+
const normalizedOrder = this.normalizeOrderCollectionsForIngress(
|
|
1538
|
+
order,
|
|
1539
|
+
"normalizeRemoteSyncedOrder"
|
|
1540
|
+
);
|
|
1541
|
+
if (this.isPendingSyncOrder(normalizedOrder))
|
|
1542
|
+
return normalizedOrder;
|
|
1493
1543
|
return {
|
|
1494
|
-
...
|
|
1544
|
+
...normalizedOrder,
|
|
1495
1545
|
need_sync: 0
|
|
1496
1546
|
};
|
|
1497
1547
|
}
|
|
1498
1548
|
mergeRemoteSnapshotWithPendingOrders(remoteOrders, existingOrders) {
|
|
1499
1549
|
const merged = remoteOrders.map((order) => this.normalizeRemoteSyncedOrder(order));
|
|
1500
|
-
for (const
|
|
1550
|
+
for (const rawOrder of existingOrders) {
|
|
1551
|
+
const order = this.normalizeOrderCollectionsForIngress(
|
|
1552
|
+
rawOrder,
|
|
1553
|
+
"mergeRemoteSnapshotWithPendingOrders.existingSQLite"
|
|
1554
|
+
);
|
|
1501
1555
|
if (!this.isPendingSyncOrder(order))
|
|
1502
1556
|
continue;
|
|
1503
1557
|
const matchIndex = this.findOrderIndexByIdentity(merged, order);
|
|
@@ -1534,7 +1588,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1534
1588
|
if (!this.dbManager || orders.length === 0) {
|
|
1535
1589
|
return;
|
|
1536
1590
|
}
|
|
1537
|
-
const ordersSnapshot = (0, import_lodash_es.cloneDeep)(orders).filter((order) => this.getOrderStorageKey(order));
|
|
1591
|
+
const ordersSnapshot = (0, import_lodash_es.cloneDeep)(orders).map((order) => this.normalizeOrderCollectionsForIngress(order, `${source}.sqliteIngress`)).filter((order) => this.getOrderStorageKey(order));
|
|
1538
1592
|
if (ordersSnapshot.length === 0) {
|
|
1539
1593
|
return;
|
|
1540
1594
|
}
|
|
@@ -1595,7 +1649,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1595
1649
|
if (!this.dbManager || !this.getOrderStorageKey(order)) {
|
|
1596
1650
|
return;
|
|
1597
1651
|
}
|
|
1598
|
-
const orderSnapshot =
|
|
1652
|
+
const orderSnapshot = this.normalizeOrderCollectionsForIngress(
|
|
1653
|
+
(0, import_lodash_es.cloneDeep)(order),
|
|
1654
|
+
`${source}.sqliteIngress`
|
|
1655
|
+
);
|
|
1599
1656
|
try {
|
|
1600
1657
|
await this.runInOrderSQLiteSaveQueue(async () => {
|
|
1601
1658
|
let writeMethod = "none";
|
|
@@ -1641,7 +1698,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1641
1698
|
`${source}.snapshotNoDb`
|
|
1642
1699
|
).list;
|
|
1643
1700
|
}
|
|
1644
|
-
const remoteSnapshot = (0, import_lodash_es.cloneDeep)(orderList)
|
|
1701
|
+
const remoteSnapshot = (0, import_lodash_es.cloneDeep)(orderList).map(
|
|
1702
|
+
(order) => this.normalizeOrderCollectionsForIngress(order, `${source}.remoteIngress`)
|
|
1703
|
+
);
|
|
1645
1704
|
let mergedSnapshot = this.compactOrderListByIdentity(
|
|
1646
1705
|
remoteSnapshot.map((order) => this.normalizeRemoteSyncedOrder(order)),
|
|
1647
1706
|
`${source}.remoteSnapshot`
|
|
@@ -18,7 +18,8 @@ export declare class ProductsModule extends BaseModule implements Module {
|
|
|
18
18
|
private productsPriceCache;
|
|
19
19
|
private readonly CACHE_MAX_DAYS;
|
|
20
20
|
private formatters;
|
|
21
|
-
private
|
|
21
|
+
private isBuiltinFormatterRegistered;
|
|
22
|
+
private isLegacyPriceFormatterEnabled;
|
|
22
23
|
private quotationPriceBridge?;
|
|
23
24
|
private quotationBridgeChannel?;
|
|
24
25
|
private quotationBridgeLoadedKey?;
|
|
@@ -36,6 +37,8 @@ export declare class ProductsModule extends BaseModule implements Module {
|
|
|
36
37
|
private lastPreloadCompletedAtMs;
|
|
37
38
|
/** IndexDB 写入串行队列,避免快照与 patch 并发交错 */
|
|
38
39
|
private productIndexDBSaveQueue;
|
|
40
|
+
/** 最近一次智能定价评估提取的 schedule 变价时间点(HH:mm),供 Server 订阅定时刷新使用 */
|
|
41
|
+
private lastScheduleTimePoints;
|
|
39
42
|
constructor(name?: string, version?: string);
|
|
40
43
|
initialize(core: PisellCore, options: any): Promise<void>;
|
|
41
44
|
/**
|
|
@@ -108,6 +111,10 @@ export declare class ProductsModule extends BaseModule implements Module {
|
|
|
108
111
|
*/
|
|
109
112
|
private prepareProductsWithPrice;
|
|
110
113
|
private getProductsPriceCacheKey;
|
|
114
|
+
/**
|
|
115
|
+
* 稳定序列化策略上下文,避免对象 key 顺序不同导致缓存 key 抖动。
|
|
116
|
+
*/
|
|
117
|
+
private stringifyStable;
|
|
111
118
|
private normalizeProductIds;
|
|
112
119
|
/**
|
|
113
120
|
* 按轻量范围返回商品 ID,不做 structuredClone。
|
|
@@ -122,14 +129,26 @@ export declare class ProductsModule extends BaseModule implements Module {
|
|
|
122
129
|
*/
|
|
123
130
|
private applyFormatters;
|
|
124
131
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
132
|
+
* 注册内置商品格式化器。
|
|
133
|
+
*
|
|
134
|
+
* 智能定价默认替代报价单逻辑;报价单 formatter 仅在 enableLegacyPriceFormatter=true 时启用。
|
|
127
135
|
* @private
|
|
128
136
|
*/
|
|
129
|
-
private
|
|
137
|
+
private registerBuiltinProductFormatters;
|
|
138
|
+
/**
|
|
139
|
+
* 是否启用旧报价单价格 formatter。
|
|
140
|
+
*
|
|
141
|
+
* 默认关闭,避免报价单逻辑覆盖智能定价结果。
|
|
142
|
+
*/
|
|
143
|
+
private shouldEnableLegacyPriceFormatter;
|
|
144
|
+
/**
|
|
145
|
+
* 返回最近一次 prepareProductsWithPrice / DataVariant 评估提取的变价时间点(HH:mm)。
|
|
146
|
+
* 供 OS Server 商品 query 订阅定时刷新使用。
|
|
147
|
+
*/
|
|
148
|
+
getLastScheduleTimePoints(): string[];
|
|
130
149
|
/**
|
|
131
150
|
* 注册商品格式化器
|
|
132
|
-
*
|
|
151
|
+
* 格式化器会按注册顺序依次执行;legacy 启用时先兜底报价,再由智能定价覆盖。
|
|
133
152
|
* @param formatter 格式化函数
|
|
134
153
|
* @param prepend 是否插入到队列开头(默认 false,追加到末尾)
|
|
135
154
|
* @example
|
|
@@ -144,8 +163,8 @@ export declare class ProductsModule extends BaseModule implements Module {
|
|
|
144
163
|
*/
|
|
145
164
|
registerFormatter(formatter: ProductFormatter, prepend?: boolean): void;
|
|
146
165
|
/**
|
|
147
|
-
*
|
|
148
|
-
* @param keepBuiltin
|
|
166
|
+
* 清空所有格式化器(包括内置智能定价格式化器)
|
|
167
|
+
* @param keepBuiltin 是否保留内置智能定价格式化器(默认 true)
|
|
149
168
|
*/
|
|
150
169
|
clearFormatters(keepBuiltin?: boolean): void;
|
|
151
170
|
/**
|