@pisell/pisellos 0.0.569 → 0.10.2
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.js +10 -6
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -3
- package/dist/model/strategy/adapter/promotion/index.js +9 -0
- package/dist/model/strategy/adapter/walletPass/evaluator.js +7 -5
- package/dist/model/strategy/adapter/walletPass/example.js +26 -3
- package/dist/model/strategy/adapter/walletPass/index.js +5 -5
- package/dist/model/strategy/adapter/walletPass/type.d.ts +0 -3
- package/dist/model/strategy/adapter/walletPass/utils.d.ts +0 -26
- package/dist/model/strategy/adapter/walletPass/utils.js +17 -92
- package/dist/model/strategy/strategy-example.js +19 -5
- package/dist/modules/BaseModule.d.ts +1 -1
- package/dist/modules/BaseModule.js +8 -10
- package/dist/modules/Cart/index.js +3 -0
- package/dist/modules/Cart/utils/cartProduct.js +1 -0
- package/dist/modules/Cart/utils/cartResource.js +0 -2
- package/dist/modules/Cart/utils/changePrice.js +9 -16
- package/dist/modules/Date/index.js +5 -1
- package/dist/modules/Discount/index.d.ts +0 -1
- package/dist/modules/Discount/index.js +7 -22
- package/dist/modules/Discount/types.d.ts +0 -1
- package/dist/modules/OpenData/index.js +2 -0
- package/dist/modules/Order/index.js +70 -40
- package/dist/modules/Payment/index.js +162 -97
- package/dist/modules/Payment/types.d.ts +4 -8
- package/dist/modules/Payment/walletpass.d.ts +0 -2
- package/dist/modules/Payment/walletpass.js +5 -4
- package/dist/modules/ProductList/index.d.ts +1 -1
- package/dist/modules/ProductList/index.js +3 -12
- package/dist/modules/ProductList/types.d.ts +0 -1
- package/dist/modules/Rules/index.js +126 -427
- package/dist/modules/SalesSummary/utils.js +1 -2
- package/dist/modules/Schedule/getDateIsInSchedule.js +0 -5
- package/dist/modules/Schedule/index.js +1 -0
- package/dist/modules/Schedule/utils.js +1 -0
- package/dist/modules/Step/index.js +1 -0
- package/dist/modules/Summary/utils.js +22 -43
- package/dist/plugins/request.js +4 -1
- package/dist/plugins/window.js +6 -2
- package/dist/server/index.js +129 -97
- package/dist/server/modules/menu/index.js +41 -32
- package/dist/server/modules/order/index.js +4 -2
- package/dist/server/modules/products/index.js +42 -24
- package/dist/server/modules/quotation/index.js +38 -29
- package/dist/server/modules/resource/index.js +4 -3
- package/dist/server/modules/schedule/index.js +35 -27
- package/dist/server/utils/product.js +1 -0
- package/dist/solution/BaseSales/index.js +41 -38
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingByStep/index.js +60 -11
- package/dist/solution/BookingByStep/utils/capacity.js +11 -1
- package/dist/solution/BookingByStep/utils/resources.js +3 -1
- package/dist/solution/BookingByStep/utils/timeslots.js +43 -2
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.js +2 -0
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +7 -6
- package/dist/solution/BookingTicket/utils/scan/handleScan.js +31 -25
- package/dist/solution/BookingTicket/utils/scan/index.js +10 -6
- package/dist/solution/BuyTickets/index.js +12 -9
- package/dist/solution/Checkout/index.js +252 -177
- package/dist/solution/Checkout/utils/index.js +16 -4
- package/dist/solution/RegisterAndLogin/index.js +76 -30
- package/dist/solution/ScanOrder/index.js +60 -50
- package/dist/solution/ShopDiscount/index.js +14 -15
- package/dist/solution/ShopDiscount/types.d.ts +4 -5
- package/dist/solution/ShopDiscount/utils.d.ts +0 -9
- package/dist/solution/ShopDiscount/utils.js +0 -9
- package/dist/solution/VenueBooking/index.d.ts +3 -31
- package/dist/solution/VenueBooking/index.js +496 -651
- package/dist/solution/VenueBooking/types.d.ts +1 -3
- package/dist/solution/VenueBooking/types.js +0 -1
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
- package/dist/solution/VenueBooking/utils/dateSummary.js +25 -12
- package/dist/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
- package/dist/solution/VenueBooking/utils/timeSlot.js +4 -9
- package/dist/types/index.d.ts +1 -1
- package/dist/utils/task.js +18 -15
- package/dist/utils/watch.js +1 -0
- package/lib/apis/picoding.js +0 -2
- package/lib/core/index.js +132 -130
- package/lib/effects/index.js +57 -46
- package/lib/index.d.ts +0 -1
- package/lib/index.js +50 -92
- package/lib/model/index.js +21 -14
- package/lib/model/strategy/adapter/dataVariant/adapter.js +50 -38
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +236 -162
- package/lib/model/strategy/adapter/dataVariant/examples.js +237 -229
- package/lib/model/strategy/adapter/dataVariant/index.js +34 -39
- package/lib/model/strategy/adapter/dataVariant/type.js +28 -57
- package/lib/model/strategy/adapter/index.js +64 -100
- package/lib/model/strategy/adapter/itemRule/adapter.js +144 -156
- package/lib/model/strategy/adapter/itemRule/evaluator.js +48 -36
- package/lib/model/strategy/adapter/itemRule/examples.js +225 -295
- package/lib/model/strategy/adapter/itemRule/index.js +57 -83
- package/lib/model/strategy/adapter/itemRule/type.js +36 -97
- package/lib/model/strategy/adapter/promotion/adapter.js +63 -84
- package/lib/model/strategy/adapter/promotion/evaluator.js +231 -381
- package/lib/model/strategy/adapter/promotion/examples.js +159 -139
- package/lib/model/strategy/adapter/promotion/index.js +49 -1
- package/lib/model/strategy/adapter/promotion/type.js +35 -199
- package/lib/model/strategy/adapter/type.js +16 -4
- package/lib/model/strategy/adapter/walletPass/evaluator.js +152 -180
- package/lib/model/strategy/adapter/walletPass/example.js +190 -217
- package/lib/model/strategy/adapter/walletPass/index.js +51 -75
- package/lib/model/strategy/adapter/walletPass/locales.js +58 -36
- package/lib/model/strategy/adapter/walletPass/type.d.ts +0 -3
- package/lib/model/strategy/adapter/walletPass/type.js +16 -4
- package/lib/model/strategy/adapter/walletPass/utils.d.ts +0 -26
- package/lib/model/strategy/adapter/walletPass/utils.js +383 -678
- package/lib/model/strategy/engine.js +168 -270
- package/lib/model/strategy/index.js +34 -49
- package/lib/model/strategy/strategy-example.js +239 -243
- package/lib/model/strategy/type.js +40 -100
- package/lib/modules/Account/index.js +53 -39
- package/lib/modules/Account/types.js +33 -20
- package/lib/modules/AccountList/index.js +154 -116
- package/lib/modules/AccountList/types.js +31 -30
- package/lib/modules/AccountList/utils.js +30 -18
- package/lib/modules/BaseModule.d.ts +1 -1
- package/lib/modules/BaseModule.js +46 -25
- package/lib/modules/BookingContext/index.js +136 -158
- package/lib/modules/BookingContext/types.js +32 -46
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +143 -131
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +82 -75
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +150 -170
- package/lib/modules/BookingContext/utils/flexible.js +55 -38
- package/lib/modules/BookingContext/utils/formatResourceList.js +34 -19
- package/lib/modules/BookingContext/utils/index.js +41 -124
- package/lib/modules/BookingContext/utils/noResource.js +70 -58
- package/lib/modules/BookingContext/utils/orderLineDisplay.js +41 -14
- package/lib/modules/BookingContext/utils/productExtend.js +155 -202
- package/lib/modules/BookingContext/utils/resourceErrors.js +53 -53
- package/lib/modules/BookingContext/utils/resourceSelection.js +41 -19
- package/lib/modules/BookingContext/utils/resources.js +167 -209
- package/lib/modules/BookingContext/utils/serviceTimes.js +116 -115
- package/lib/modules/BookingContext/utils/timeSlices.js +80 -70
- package/lib/modules/Cart/index.js +124 -170
- package/lib/modules/Cart/types.js +51 -46
- package/lib/modules/Cart/utils/cartAccount.js +39 -40
- package/lib/modules/Cart/utils/cartDate.js +61 -56
- package/lib/modules/Cart/utils/cartDiscount.js +33 -28
- package/lib/modules/Cart/utils/cartNote.js +32 -27
- package/lib/modules/Cart/utils/cartProduct.js +251 -321
- package/lib/modules/Cart/utils/cartRelationForms.js +35 -29
- package/lib/modules/Cart/utils/cartResource.js +78 -72
- package/lib/modules/Cart/utils/changePrice.js +50 -28
- package/lib/modules/Cart/utils/index.js +48 -106
- package/lib/modules/Customer/constants.js +34 -13
- package/lib/modules/Customer/index.js +169 -232
- package/lib/modules/Customer/types.js +35 -38
- package/lib/modules/Date/index.js +115 -116
- package/lib/modules/Date/types.js +28 -16
- package/lib/modules/Date/utils.js +123 -174
- package/lib/modules/Discount/index.d.ts +0 -1
- package/lib/modules/Discount/index.js +128 -130
- package/lib/modules/Discount/types.d.ts +0 -1
- package/lib/modules/Discount/types.js +31 -9
- package/lib/modules/Guests/index.js +56 -30
- package/lib/modules/Guests/types.js +33 -23
- package/lib/modules/Holder/index.js +189 -209
- package/lib/modules/Holder/types.js +16 -4
- package/lib/modules/Holder/utils.js +49 -20
- package/lib/modules/OpenData/index.js +76 -69
- package/lib/modules/OpenData/types.js +16 -4
- package/lib/modules/OpenData/utils.js +78 -44
- package/lib/modules/Order/index.js +1909 -1572
- package/lib/modules/Order/types.js +35 -78
- package/lib/modules/Order/utils/bundleDiscountHydration.js +74 -41
- package/lib/modules/Order/utils/manualProductDiscount.js +123 -124
- package/lib/modules/Order/utils/orderCollectionIdentity.js +210 -148
- package/lib/modules/Order/utils.js +634 -799
- package/lib/modules/Payment/cash.js +33 -20
- package/lib/modules/Payment/cashRecommendationAlgorithm.js +76 -145
- package/lib/modules/Payment/eftpos.js +30 -16
- package/lib/modules/Payment/index.js +378 -518
- package/lib/modules/Payment/mx51.js +0 -1
- package/lib/modules/Payment/types.d.ts +4 -8
- package/lib/modules/Payment/types.js +107 -216
- package/lib/modules/Payment/utils.js +48 -51
- package/lib/modules/Payment/walletpass.d.ts +0 -2
- package/lib/modules/Payment/walletpass.js +211 -226
- package/lib/modules/Product/index.js +46 -51
- package/lib/modules/Product/types.js +16 -4
- package/lib/modules/Product/utils.js +33 -32
- package/lib/modules/ProductList/index.d.ts +1 -1
- package/lib/modules/ProductList/index.js +117 -117
- package/lib/modules/ProductList/types.d.ts +0 -1
- package/lib/modules/ProductList/types.js +31 -9
- package/lib/modules/Quotation/index.js +100 -66
- package/lib/modules/Quotation/types.js +16 -4
- package/lib/modules/Resource/index.js +59 -27
- package/lib/modules/Resource/types.js +32 -22
- package/lib/modules/Resource/utils.js +38 -30
- package/lib/modules/ResourcePlanner/index.js +61 -60
- package/lib/modules/ResourcePlanner/planner.js +384 -346
- package/lib/modules/ResourcePlanner/types.js +16 -4
- package/lib/modules/Rules/index.js +903 -1475
- package/lib/modules/Rules/types.js +40 -17
- package/lib/modules/SalesSummary/index.js +90 -85
- package/lib/modules/SalesSummary/types.js +16 -4
- package/lib/modules/SalesSummary/utils.js +427 -351
- package/lib/modules/ScanOrderLogger/index.js +79 -59
- package/lib/modules/ScanOrderLogger/providers/feishu.js +78 -54
- package/lib/modules/ScanOrderLogger/providers/grafana.js +36 -13
- package/lib/modules/ScanOrderLogger/types.js +16 -4
- package/lib/modules/Schedule/getDateIsInSchedule.js +163 -339
- package/lib/modules/Schedule/index.js +114 -100
- package/lib/modules/Schedule/type.js +16 -4
- package/lib/modules/Schedule/types.js +16 -4
- package/lib/modules/Schedule/utils.js +291 -433
- package/lib/modules/Step/index.js +52 -40
- package/lib/modules/Step/tyeps.js +16 -4
- package/lib/modules/Summary/index.js +71 -66
- package/lib/modules/Summary/types.js +16 -4
- package/lib/modules/Summary/utils.js +418 -791
- package/lib/modules/SurchargeList/index.js +60 -46
- package/lib/modules/SurchargeList/types.js +16 -4
- package/lib/modules/index.js +63 -245
- package/lib/plugins/app.js +16 -4
- package/lib/plugins/index.js +25 -36
- package/lib/plugins/request.js +126 -137
- package/lib/plugins/shopStore.js +16 -4
- package/lib/plugins/user.js +16 -4
- package/lib/plugins/window.js +179 -171
- package/lib/server/index.js +2337 -2675
- package/lib/server/modules/floor-plan/index.js +123 -102
- package/lib/server/modules/floor-plan/types.js +30 -15
- package/lib/server/modules/index.js +68 -106
- package/lib/server/modules/menu/index.js +122 -146
- package/lib/server/modules/menu/types.js +31 -18
- package/lib/server/modules/order/index.js +642 -567
- package/lib/server/modules/order/types.js +32 -117
- package/lib/server/modules/order/utils/filterBookings.js +194 -219
- package/lib/server/modules/order/utils/filterOrders.js +92 -118
- package/lib/server/modules/payment/index.js +83 -59
- package/lib/server/modules/payment/types.js +16 -4
- package/lib/server/modules/products/index.js +459 -575
- package/lib/server/modules/products/types.js +34 -44
- package/lib/server/modules/quotation/index.js +172 -137
- package/lib/server/modules/quotation/types.js +31 -21
- package/lib/server/modules/resource/index.js +184 -213
- package/lib/server/modules/resource/types.js +33 -42
- package/lib/server/modules/schedule/index.js +123 -135
- package/lib/server/modules/schedule/types.js +21 -14
- package/lib/server/modules/schedule/utils.js +163 -334
- package/lib/server/types.js +16 -4
- package/lib/server/utils/index.js +23 -25
- package/lib/server/utils/product.js +139 -196
- package/lib/server/utils/schedule.js +41 -34
- package/lib/server/utils/small-ticket.js +456 -478
- package/lib/server/utils/time.js +49 -40
- package/lib/solution/BaseSales/index.js +1016 -850
- package/lib/solution/BaseSales/types.js +37 -41
- package/lib/solution/BaseSales/utils/cartPromotion.js +460 -611
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +105 -85
- package/lib/solution/BaseSales/utils/quotationPrice.js +114 -56
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +143 -102
- package/lib/solution/BaseSales/utils.js +140 -155
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingByStep/index.js +1340 -1530
- package/lib/solution/BookingByStep/types.js +99 -40
- package/lib/solution/BookingByStep/utils/capacity.js +160 -192
- package/lib/solution/BookingByStep/utils/products.js +52 -42
- package/lib/solution/BookingByStep/utils/resources.js +330 -527
- package/lib/solution/BookingByStep/utils/stock.js +44 -65
- package/lib/solution/BookingByStep/utils/timeslots.js +131 -129
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.js +459 -543
- package/lib/solution/BookingTicket/types.js +77 -99
- package/lib/solution/BookingTicket/utils/addProductDecision.js +184 -219
- package/lib/solution/BookingTicket/utils/addTimeAvailability.js +89 -58
- package/lib/solution/BookingTicket/utils/bookingStatus.js +78 -107
- package/lib/solution/BookingTicket/utils/cartView.js +94 -110
- package/lib/solution/BookingTicket/utils/exampleData.js +0 -185
- package/lib/solution/BookingTicket/utils/orderCustomer.js +41 -18
- package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +86 -219
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +93 -144
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +91 -79
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +41 -54
- package/lib/solution/BookingTicket/utils/scan/handleScan.js +81 -84
- package/lib/solution/BookingTicket/utils/scan/index.js +104 -98
- package/lib/solution/BookingTicket/utils/scan/scanCache.js +43 -90
- package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +64 -52
- package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +58 -56
- package/lib/solution/BuyTickets/index.js +70 -67
- package/lib/solution/BuyTickets/types.js +38 -22
- package/lib/solution/Checkout/index.js +1158 -1451
- package/lib/solution/Checkout/types.js +61 -91
- package/lib/solution/Checkout/utils/index.js +156 -228
- package/lib/solution/PlaceOrder/index.js +0 -55
- package/lib/solution/RegisterAndLogin/config.js +460 -493
- package/lib/solution/RegisterAndLogin/index.js +630 -633
- package/lib/solution/RegisterAndLogin/types.js +76 -189
- package/lib/solution/RegisterAndLogin/utils.js +125 -183
- package/lib/solution/Sales/index.js +320 -317
- package/lib/solution/Sales/types.js +33 -27
- package/lib/solution/ScanOrder/index.js +862 -831
- package/lib/solution/ScanOrder/types.js +34 -33
- package/lib/solution/ScanOrder/utils.js +371 -406
- package/lib/solution/ShopDiscount/index.js +233 -235
- package/lib/solution/ShopDiscount/types.d.ts +4 -5
- package/lib/solution/ShopDiscount/types.js +37 -15
- package/lib/solution/ShopDiscount/utils.d.ts +0 -9
- package/lib/solution/ShopDiscount/utils.js +172 -309
- package/lib/solution/UnifiedBookingSales/index.js +405 -379
- package/lib/solution/UnifiedBookingSales/types.js +31 -12
- package/lib/solution/VenueBooking/index.d.ts +3 -31
- package/lib/solution/VenueBooking/index.js +916 -967
- package/lib/solution/VenueBooking/types.d.ts +1 -3
- package/lib/solution/VenueBooking/types.js +39 -20
- package/lib/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
- package/lib/solution/VenueBooking/utils/dateSummary.js +62 -25
- package/lib/solution/VenueBooking/utils/resource.js +54 -31
- package/lib/solution/VenueBooking/utils/slotMerge.js +107 -94
- package/lib/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
- package/lib/solution/VenueBooking/utils/timeSlot.js +133 -138
- package/lib/solution/VenueBooking/utils.js +67 -130
- package/lib/solution/index.js +41 -124
- package/lib/store/createStore.js +29 -32
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.js +16 -4
- package/lib/utils/task.js +36 -36
- package/lib/utils/watch.js +47 -81
- package/package.json +2 -4
- package/dist/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
- package/dist/solution/VenueBooking/utils/smartPricing.js +0 -233
- package/lib/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
- package/lib/solution/VenueBooking/utils/smartPricing.js +0 -192
|
@@ -1,65 +1,75 @@
|
|
|
1
|
-
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
2
28
|
|
|
3
|
-
|
|
4
|
-
|
|
29
|
+
// src/server/modules/order/index.ts
|
|
30
|
+
var order_exports = {};
|
|
31
|
+
__export(order_exports, {
|
|
32
|
+
OrderModule: () => OrderModule
|
|
5
33
|
});
|
|
6
|
-
exports
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
* 仅用于排查增量身份索引是否遗漏了重复订单,不应在生产常开。
|
|
31
|
-
*/
|
|
32
|
-
const ORDER_MERGE_SELF_CHECK = false;
|
|
33
|
-
const ORDER_AUTHORITATIVE_COLLECTION_FIELDS = ['products', 'bookings', 'payments'];
|
|
34
|
-
const ORDER_COLLECTION_KIND_BY_FIELD = {
|
|
35
|
-
products: 'product',
|
|
36
|
-
bookings: 'booking',
|
|
37
|
-
payments: 'payment'
|
|
34
|
+
module.exports = __toCommonJS(order_exports);
|
|
35
|
+
var import_lodash_es = require("lodash-es");
|
|
36
|
+
var import_dayjs = __toESM(require("dayjs"));
|
|
37
|
+
var import_BaseModule = require("../../../modules/BaseModule");
|
|
38
|
+
var import_orderCollectionIdentity = require("../../../modules/Order/utils/orderCollectionIdentity");
|
|
39
|
+
var import_types = require("./types");
|
|
40
|
+
var INDEXDB_STORE_NAME = "orders";
|
|
41
|
+
var ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY = "server_order_last_full_fetch_at";
|
|
42
|
+
var ORDER_SYNC_THROTTLE_MS_STORAGE_KEY = "order_sync_throttle_ms";
|
|
43
|
+
var DEFAULT_ORDER_SYNC_THROTTLE_MS = 2e3;
|
|
44
|
+
var ORDER_SQLITE_DEDUPE_MS = 15e3;
|
|
45
|
+
var ORDER_SILENT_REFRESH_MIN_INTERVAL_MS = 3e4;
|
|
46
|
+
var ORDER_BUSINESS_WRITE_SOURCES = /* @__PURE__ */ new Set([
|
|
47
|
+
"upsertOrdersFromRemote",
|
|
48
|
+
"upsertPendingSyncOrders",
|
|
49
|
+
"overwriteExistingOrder",
|
|
50
|
+
"markOrderSyncedByExternalSaleNumber"
|
|
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"
|
|
38
58
|
};
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Order 模块 - 基础框架
|
|
42
|
-
*/
|
|
43
|
-
class OrderModule extends _BaseModule.BaseModule {
|
|
44
|
-
defaultName = 'order';
|
|
45
|
-
defaultVersion = '1.0.0';
|
|
46
|
-
store;
|
|
47
|
-
dbManager;
|
|
48
|
-
orderDataSource;
|
|
49
|
-
pendingSyncMessages = [];
|
|
50
|
-
syncTimer;
|
|
51
|
-
isProcessingSyncBatch = false;
|
|
52
|
-
isIdlePhase = true;
|
|
53
|
-
logger; // LoggerManager 实例
|
|
54
|
-
storage;
|
|
55
|
-
orderSQLiteSaveQueue = Promise.resolve(); /** 按 storageKey 记录最近一次 SQLite 写入来源与时间,用于去重 */
|
|
56
|
-
recentSqliteWriteByStorageKey = new Map();
|
|
57
|
-
/** 最近一次 SSE 全量拉取完成时间 */
|
|
58
|
-
lastServerFullFetchAtMs = 0;
|
|
59
|
+
var OrderModule = class extends import_BaseModule.BaseModule {
|
|
59
60
|
constructor(name, version) {
|
|
60
61
|
super(name, version);
|
|
62
|
+
this.defaultName = "order";
|
|
63
|
+
this.defaultVersion = "1.0.0";
|
|
64
|
+
this.pendingSyncMessages = [];
|
|
65
|
+
this.isProcessingSyncBatch = false;
|
|
66
|
+
this.isIdlePhase = true;
|
|
67
|
+
this.orderSQLiteSaveQueue = Promise.resolve();
|
|
68
|
+
/** 按 storageKey 记录最近一次 SQLite 写入来源与时间,用于去重 */
|
|
69
|
+
this.recentSqliteWriteByStorageKey = /* @__PURE__ */ new Map();
|
|
70
|
+
/** 最近一次 SSE 全量拉取完成时间 */
|
|
71
|
+
this.lastServerFullFetchAtMs = 0;
|
|
61
72
|
}
|
|
62
|
-
|
|
63
73
|
/**
|
|
64
74
|
* 广播订单变更事件,兼容全量列表订阅并额外携带本次变更订单。
|
|
65
75
|
*
|
|
@@ -67,42 +77,44 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
67
77
|
* await this.emitOrdersChanged([freshOrder], 'pubsub.bodyUpsert')
|
|
68
78
|
*/
|
|
69
79
|
async emitOrdersChanged(changedOrders = [], source) {
|
|
80
|
+
console.log("触发emitOrdersChanged");
|
|
70
81
|
const payload = {
|
|
71
82
|
list: this.store.list,
|
|
72
|
-
changedOrders: changedOrders.map(order => this.normalizeOrderForMemoryList(order)),
|
|
83
|
+
changedOrders: changedOrders.map((order) => this.normalizeOrderForMemoryList(order)),
|
|
73
84
|
source
|
|
74
85
|
};
|
|
75
|
-
await this.core.effects.emit(
|
|
86
|
+
await this.core.effects.emit(import_types.OrderHooks.onOrdersChanged, payload);
|
|
76
87
|
}
|
|
77
88
|
async initialize(core, options) {
|
|
89
|
+
var _a;
|
|
78
90
|
this.core = core;
|
|
79
|
-
this.store = options
|
|
80
|
-
if (!this.store.map)
|
|
81
|
-
|
|
82
|
-
const
|
|
91
|
+
this.store = options == null ? void 0 : options.store;
|
|
92
|
+
if (!this.store.map)
|
|
93
|
+
this.store.map = /* @__PURE__ */ new Map();
|
|
94
|
+
const appPlugin = core.getPlugin("app");
|
|
95
|
+
const app = appPlugin == null ? void 0 : appPlugin.getApp();
|
|
83
96
|
if (app) {
|
|
84
97
|
this.dbManager = app.sqlite;
|
|
85
98
|
this.logger = app.logger;
|
|
86
99
|
this.storage = app.storage;
|
|
87
100
|
this.updateCreateStore();
|
|
88
101
|
}
|
|
89
|
-
if (Array.isArray(options
|
|
90
|
-
this.store.list = options.initialState.list.map(order => this.normalizeOrderForMemoryList(order));
|
|
102
|
+
if (Array.isArray((_a = options == null ? void 0 : options.initialState) == null ? void 0 : _a.list)) {
|
|
103
|
+
this.store.list = options.initialState.list.map((order) => this.normalizeOrderForMemoryList(order));
|
|
91
104
|
this.syncOrdersMap();
|
|
92
|
-
this.emitOrdersChanged([],
|
|
105
|
+
this.emitOrdersChanged([], "initialState");
|
|
93
106
|
} else {
|
|
94
107
|
this.store.list = [];
|
|
95
|
-
this.store.map = new Map();
|
|
108
|
+
this.store.map = /* @__PURE__ */ new Map();
|
|
96
109
|
}
|
|
97
110
|
this.initOrderDataSource();
|
|
98
111
|
this.setupOrderSync();
|
|
99
|
-
this.logInfo(
|
|
112
|
+
this.logInfo("OrderServer模块初始化完成", {
|
|
100
113
|
hasDbManager: !!this.dbManager,
|
|
101
114
|
hasLogger: !!this.logger,
|
|
102
115
|
initialOrderCount: this.store.list.length
|
|
103
116
|
});
|
|
104
117
|
}
|
|
105
|
-
|
|
106
118
|
/**
|
|
107
119
|
* 记录信息日志
|
|
108
120
|
* @param title 日志标题
|
|
@@ -112,16 +124,14 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
112
124
|
try {
|
|
113
125
|
if (this.logger) {
|
|
114
126
|
this.logger.addLog({
|
|
115
|
-
type:
|
|
127
|
+
type: "info",
|
|
116
128
|
title: `[OrderServerModule] ${title}`,
|
|
117
129
|
metadata: metadata || {}
|
|
118
130
|
});
|
|
119
131
|
}
|
|
120
132
|
} catch {
|
|
121
|
-
// 日志记录失败不影响主流程
|
|
122
133
|
}
|
|
123
134
|
}
|
|
124
|
-
|
|
125
135
|
/**
|
|
126
136
|
* 记录错误日志
|
|
127
137
|
* @param title 日志标题
|
|
@@ -131,42 +141,39 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
131
141
|
try {
|
|
132
142
|
if (this.logger) {
|
|
133
143
|
this.logger.addLog({
|
|
134
|
-
type:
|
|
144
|
+
type: "error",
|
|
135
145
|
title: `[OrderServerModule] ${title}`,
|
|
136
146
|
metadata: metadata || {}
|
|
137
147
|
});
|
|
138
148
|
}
|
|
139
149
|
} catch {
|
|
140
|
-
// 日志记录失败不影响主流程
|
|
141
150
|
}
|
|
142
151
|
}
|
|
143
152
|
logWarning(title, metadata) {
|
|
144
153
|
try {
|
|
145
154
|
if (this.logger) {
|
|
146
155
|
this.logger.addLog({
|
|
147
|
-
type:
|
|
156
|
+
type: "warning",
|
|
148
157
|
title: `[OrderServerModule] ${title}`,
|
|
149
158
|
metadata: metadata || {}
|
|
150
159
|
});
|
|
151
160
|
}
|
|
152
161
|
} catch {
|
|
153
|
-
// 日志记录失败不影响主流程
|
|
154
162
|
}
|
|
155
163
|
}
|
|
156
|
-
|
|
157
164
|
/**
|
|
158
165
|
* 在订单进入内存或 SQLite 前统一压缩子项强身份重复并补齐协议 UID。
|
|
159
166
|
* 仅记录计数与订单标识,不输出商品、预约、支付或客户明细。
|
|
160
167
|
*/
|
|
161
168
|
normalizeOrderCollectionsForIngress(order, source) {
|
|
162
|
-
const result = (0,
|
|
163
|
-
const kinds = [
|
|
164
|
-
const hasChanges = kinds.some(kind => {
|
|
169
|
+
const result = (0, import_orderCollectionIdentity.normalizeOrderCollections)(order);
|
|
170
|
+
const kinds = ["product", "booking", "payment"];
|
|
171
|
+
const hasChanges = kinds.some((kind) => {
|
|
165
172
|
const stats = result.stats[kind];
|
|
166
173
|
return stats.backfilledUidCount > 0 || stats.collapsedDuplicateCount > 0 || stats.uidConflictCount > 0 || stats.anonymousRowCount > 0;
|
|
167
174
|
});
|
|
168
175
|
if (hasChanges) {
|
|
169
|
-
const summarize = stats => ({
|
|
176
|
+
const summarize = (stats) => ({
|
|
170
177
|
backfilled_uid_count: stats.backfilledUidCount,
|
|
171
178
|
collapsed_duplicate_count: stats.collapsedDuplicateCount,
|
|
172
179
|
uid_conflict_count: stats.uidConflictCount,
|
|
@@ -174,44 +181,50 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
174
181
|
});
|
|
175
182
|
const context = {
|
|
176
183
|
source,
|
|
177
|
-
order_id: order
|
|
178
|
-
external_sale_number: order
|
|
184
|
+
order_id: (order == null ? void 0 : order.order_id) ?? null,
|
|
185
|
+
external_sale_number: (order == null ? void 0 : order.external_sale_number) ?? null,
|
|
179
186
|
products: summarize(result.stats.product),
|
|
180
187
|
bookings: summarize(result.stats.booking),
|
|
181
188
|
payments: summarize(result.stats.payment)
|
|
182
189
|
};
|
|
183
|
-
const hasUnsafeIdentity = kinds.some(kind => {
|
|
190
|
+
const hasUnsafeIdentity = kinds.some((kind) => {
|
|
184
191
|
const stats = result.stats[kind];
|
|
185
192
|
return stats.uidConflictCount > 0 || stats.anonymousRowCount > 0;
|
|
186
193
|
});
|
|
187
194
|
if (hasUnsafeIdentity) {
|
|
188
|
-
this.logWarning(
|
|
195
|
+
this.logWarning("订单子项身份存在冲突或匿名行", context);
|
|
189
196
|
} else {
|
|
190
|
-
this.logInfo(
|
|
197
|
+
this.logInfo("订单子项身份已规范化", context);
|
|
191
198
|
}
|
|
192
199
|
}
|
|
193
200
|
return result.order;
|
|
194
201
|
}
|
|
195
|
-
|
|
196
202
|
/**
|
|
197
203
|
* incoming 决定权威成员集合;同一持久化行仍从 existing 补齐 incoming 省略的本地展示字段。
|
|
198
204
|
*/
|
|
199
205
|
mergeAuthoritativeOrderCollection(field, existing, incoming, uidRemaps = []) {
|
|
200
206
|
const kind = ORDER_COLLECTION_KIND_BY_FIELD[field];
|
|
201
207
|
const existingItems = Array.isArray(existing) ? existing : [];
|
|
202
|
-
return incoming.map(incomingItem => {
|
|
203
|
-
const existingItem = existingItems.find(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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);
|
|
207
216
|
if (mergedUid) {
|
|
208
|
-
for (const from of new Set([
|
|
209
|
-
|
|
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;
|
|
210
223
|
uidRemaps.push({
|
|
211
224
|
kind,
|
|
212
225
|
from,
|
|
213
226
|
to: mergedUid,
|
|
214
|
-
persistentId: (0,
|
|
227
|
+
persistentId: (0, import_orderCollectionIdentity.getOrderCollectionPersistentId)(kind, incomingItem) || (0, import_orderCollectionIdentity.getOrderCollectionPersistentId)(kind, existingItem)
|
|
215
228
|
});
|
|
216
229
|
}
|
|
217
230
|
}
|
|
@@ -219,17 +232,25 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
219
232
|
});
|
|
220
233
|
}
|
|
221
234
|
reconcileOverwriteOrderCollections(existing, incoming) {
|
|
222
|
-
const reconciled = (0,
|
|
235
|
+
const reconciled = (0, import_lodash_es.cloneDeep)(incoming);
|
|
223
236
|
const existingRecord = existing;
|
|
224
237
|
const incomingRecord = incoming;
|
|
225
238
|
const uidRemaps = [];
|
|
226
239
|
for (const field of ORDER_AUTHORITATIVE_COLLECTION_FIELDS) {
|
|
227
|
-
if (!Array.isArray(incomingRecord[field]))
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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
|
+
);
|
|
231
253
|
}
|
|
232
|
-
|
|
233
254
|
/**
|
|
234
255
|
* 记录订单最近一次 SQLite 写入,供 pubsub 回声去重使用。
|
|
235
256
|
*
|
|
@@ -240,14 +261,11 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
240
261
|
const now = Date.now();
|
|
241
262
|
for (const order of orders) {
|
|
242
263
|
const storageKey = this.getOrderStorageKey(order);
|
|
243
|
-
if (!storageKey)
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
ts: now
|
|
247
|
-
});
|
|
264
|
+
if (!storageKey)
|
|
265
|
+
continue;
|
|
266
|
+
this.recentSqliteWriteByStorageKey.set(storageKey, { source, ts: now });
|
|
248
267
|
}
|
|
249
268
|
}
|
|
250
|
-
|
|
251
269
|
/**
|
|
252
270
|
* 过滤 pubsub 触发的冗余 SQLite patch(业务 API 刚写入过的 update 回声)。
|
|
253
271
|
*
|
|
@@ -255,12 +273,9 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
255
273
|
* const { toWrite, skipped } = this.filterRedundantPatchOrders('pubsub.bodyUpsert', orders, mergeActions)
|
|
256
274
|
*/
|
|
257
275
|
filterRedundantPatchOrders(source, orders, mergeActions) {
|
|
258
|
-
const eligibleSkipSources = new Set([
|
|
276
|
+
const eligibleSkipSources = /* @__PURE__ */ new Set(["pubsub.bodyUpsert", "pubsub.httpRefresh"]);
|
|
259
277
|
if (!eligibleSkipSources.has(source)) {
|
|
260
|
-
return {
|
|
261
|
-
toWrite: orders,
|
|
262
|
-
skipped: []
|
|
263
|
-
};
|
|
278
|
+
return { toWrite: orders, skipped: [] };
|
|
264
279
|
}
|
|
265
280
|
const now = Date.now();
|
|
266
281
|
const toWrite = [];
|
|
@@ -271,11 +286,9 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
271
286
|
toWrite.push(order);
|
|
272
287
|
continue;
|
|
273
288
|
}
|
|
274
|
-
const orderKey = order.order_id !==
|
|
275
|
-
const mergeAction = orderKey ? mergeActions[orderKey] :
|
|
276
|
-
|
|
277
|
-
// 新增单必须落库,不参与去重
|
|
278
|
-
if (mergeAction === 'insert') {
|
|
289
|
+
const orderKey = order.order_id !== void 0 && order.order_id !== null ? this.getIdKey(order.order_id) : "";
|
|
290
|
+
const mergeAction = orderKey ? mergeActions[orderKey] : void 0;
|
|
291
|
+
if (mergeAction === "insert") {
|
|
279
292
|
toWrite.push(order);
|
|
280
293
|
continue;
|
|
281
294
|
}
|
|
@@ -284,7 +297,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
284
297
|
skipped.push({
|
|
285
298
|
orderId: order.order_id ?? null,
|
|
286
299
|
storageKey,
|
|
287
|
-
reason:
|
|
300
|
+
reason: "skip_pubsub_echo_after_business_write",
|
|
288
301
|
lastSource: recent.source,
|
|
289
302
|
elapsedMs: now - recent.ts
|
|
290
303
|
});
|
|
@@ -292,12 +305,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
292
305
|
}
|
|
293
306
|
toWrite.push(order);
|
|
294
307
|
}
|
|
295
|
-
return {
|
|
296
|
-
toWrite,
|
|
297
|
-
skipped
|
|
298
|
-
};
|
|
308
|
+
return { toWrite, skipped };
|
|
299
309
|
}
|
|
300
|
-
|
|
301
310
|
/**
|
|
302
311
|
* 过滤 pubsub HTTP 增量拉取 ids:本地刚由业务 API 写入的单可跳过 HTTP。
|
|
303
312
|
*
|
|
@@ -315,8 +324,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
315
324
|
continue;
|
|
316
325
|
}
|
|
317
326
|
const storageKey = this.getOrderStorageKey(existing);
|
|
318
|
-
const recent = storageKey ? this.recentSqliteWriteByStorageKey.get(storageKey) :
|
|
319
|
-
if (recent && recent.source ===
|
|
327
|
+
const recent = storageKey ? this.recentSqliteWriteByStorageKey.get(storageKey) : void 0;
|
|
328
|
+
if (recent && recent.source === "upsertOrdersFromRemote" && now - recent.ts < ORDER_SQLITE_DEDUPE_MS) {
|
|
320
329
|
skipped.push({
|
|
321
330
|
orderId: id,
|
|
322
331
|
lastSource: recent.source,
|
|
@@ -326,12 +335,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
326
335
|
}
|
|
327
336
|
toFetch.push(id);
|
|
328
337
|
}
|
|
329
|
-
return {
|
|
330
|
-
toFetch,
|
|
331
|
-
skipped
|
|
332
|
-
};
|
|
338
|
+
return { toFetch, skipped };
|
|
333
339
|
}
|
|
334
|
-
|
|
335
340
|
/**
|
|
336
341
|
* 解析 pubsub 消息会走哪条同步分支,便于对照为何触发 HTTP 重拉或 body 直写。
|
|
337
342
|
*
|
|
@@ -340,24 +345,25 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
340
345
|
* // => { route: 'httpRefresh.batchIds', ... }
|
|
341
346
|
*/
|
|
342
347
|
resolveSyncMessageRoute(msg) {
|
|
348
|
+
var _a;
|
|
343
349
|
const hasBatchIds = Array.isArray(msg.ids) && msg.ids.length > 0;
|
|
344
350
|
const singleIdRaw = msg.id ?? msg.order_id;
|
|
345
|
-
const hasSingleId = !hasBatchIds && singleIdRaw !==
|
|
351
|
+
const hasSingleId = !hasBatchIds && singleIdRaw !== void 0 && singleIdRaw !== null;
|
|
346
352
|
const normalizedBody = this.normalizeOrderSyncPayload(msg.body || msg.data);
|
|
347
353
|
if (hasBatchIds) {
|
|
348
354
|
return {
|
|
349
|
-
route:
|
|
355
|
+
route: "httpRefresh.batchIds",
|
|
350
356
|
hasBatchIds: true,
|
|
351
357
|
hasSingleId: false,
|
|
352
358
|
hasNormalizedBody: !!normalizedBody,
|
|
353
359
|
singleId: null,
|
|
354
360
|
batchIds: msg.ids || [],
|
|
355
|
-
bodyOrderId: normalizedBody
|
|
361
|
+
bodyOrderId: (normalizedBody == null ? void 0 : normalizedBody.order_id) ?? null
|
|
356
362
|
};
|
|
357
363
|
}
|
|
358
364
|
if (hasSingleId && normalizedBody) {
|
|
359
365
|
return {
|
|
360
|
-
route:
|
|
366
|
+
route: "bodyUpsert",
|
|
361
367
|
hasBatchIds: false,
|
|
362
368
|
hasSingleId: true,
|
|
363
369
|
hasNormalizedBody: true,
|
|
@@ -368,70 +374,77 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
368
374
|
}
|
|
369
375
|
if (hasSingleId) {
|
|
370
376
|
return {
|
|
371
|
-
route:
|
|
377
|
+
route: "httpRefresh.singleId",
|
|
372
378
|
hasBatchIds: false,
|
|
373
379
|
hasSingleId: true,
|
|
374
380
|
hasNormalizedBody: !!normalizedBody,
|
|
375
381
|
singleId: singleIdRaw,
|
|
376
382
|
batchIds: [],
|
|
377
|
-
bodyOrderId: normalizedBody
|
|
383
|
+
bodyOrderId: (normalizedBody == null ? void 0 : normalizedBody.order_id) ?? null
|
|
378
384
|
};
|
|
379
385
|
}
|
|
380
|
-
if (msg.relation_order_ids
|
|
386
|
+
if ((_a = msg.relation_order_ids) == null ? void 0 : _a.length) {
|
|
381
387
|
return {
|
|
382
|
-
route:
|
|
388
|
+
route: "httpRefresh.relationIds",
|
|
383
389
|
hasBatchIds: false,
|
|
384
390
|
hasSingleId: false,
|
|
385
391
|
hasNormalizedBody: !!normalizedBody,
|
|
386
392
|
singleId: null,
|
|
387
393
|
batchIds: msg.relation_order_ids,
|
|
388
|
-
bodyOrderId: normalizedBody
|
|
394
|
+
bodyOrderId: (normalizedBody == null ? void 0 : normalizedBody.order_id) ?? null
|
|
389
395
|
};
|
|
390
396
|
}
|
|
391
397
|
return {
|
|
392
|
-
route:
|
|
398
|
+
route: "noop",
|
|
393
399
|
hasBatchIds: false,
|
|
394
400
|
hasSingleId: false,
|
|
395
401
|
hasNormalizedBody: !!normalizedBody,
|
|
396
402
|
singleId: null,
|
|
397
403
|
batchIds: [],
|
|
398
|
-
bodyOrderId: normalizedBody
|
|
404
|
+
bodyOrderId: (normalizedBody == null ? void 0 : normalizedBody.order_id) ?? null
|
|
399
405
|
};
|
|
400
406
|
}
|
|
401
407
|
updateCreateStore() {
|
|
402
|
-
const appPlugin = this.core.getPlugin(
|
|
403
|
-
const app = appPlugin
|
|
408
|
+
const appPlugin = this.core.getPlugin("app");
|
|
409
|
+
const app = appPlugin == null ? void 0 : appPlugin.getApp();
|
|
404
410
|
if (app) {
|
|
405
|
-
const coreData = app.data.store.getStore().getDataByModel(
|
|
406
|
-
if (coreData
|
|
407
|
-
const today = (0,
|
|
408
|
-
if (coreData
|
|
411
|
+
const coreData = app.data.store.getStore().getDataByModel("core");
|
|
412
|
+
if (coreData == null ? void 0 : coreData.core) {
|
|
413
|
+
const today = (0, import_dayjs.default)();
|
|
414
|
+
if (coreData == null ? void 0 : coreData.core.operating_day_boundary) {
|
|
409
415
|
const operatingDayBoundary = coreData.core.operating_day_boundary;
|
|
410
|
-
if (operatingDayBoundary.type ===
|
|
411
|
-
const boundaryTime = String(operatingDayBoundary.time ||
|
|
412
|
-
const boundaryStart = (0,
|
|
416
|
+
if (operatingDayBoundary.type === "start_time") {
|
|
417
|
+
const boundaryTime = String(operatingDayBoundary.time || "").trim();
|
|
418
|
+
const boundaryStart = (0, import_dayjs.default)(`${today.format("YYYY-MM-DD")} ${boundaryTime}`);
|
|
413
419
|
if (boundaryStart.isValid()) {
|
|
414
420
|
const isAfterBoundary = today.isAfter(boundaryStart);
|
|
415
|
-
const queryStart = isAfterBoundary ? today.startOf(
|
|
416
|
-
const queryEnd = isAfterBoundary ? today.add(1,
|
|
421
|
+
const queryStart = isAfterBoundary ? today.startOf("day") : today.subtract(1, "day").startOf("day");
|
|
422
|
+
const queryEnd = isAfterBoundary ? today.add(1, "day").endOf("day") : today.endOf("day");
|
|
417
423
|
this.store.createdAtQuery = {
|
|
418
|
-
sales_time_between: [
|
|
424
|
+
sales_time_between: [
|
|
425
|
+
queryStart.format("YYYY-MM-DD HH:mm:ss"),
|
|
426
|
+
queryEnd.format("YYYY-MM-DD HH:mm:ss")
|
|
427
|
+
]
|
|
419
428
|
};
|
|
420
429
|
} else {
|
|
421
|
-
// 边界时间异常时回退到自然日,避免 createdAtQuery 为空导致后续查询异常
|
|
422
430
|
this.store.createdAtQuery = {
|
|
423
|
-
sales_time_between: [
|
|
431
|
+
sales_time_between: [
|
|
432
|
+
today.startOf("day").format("YYYY-MM-DD HH:mm:ss"),
|
|
433
|
+
today.endOf("day").format("YYYY-MM-DD HH:mm:ss")
|
|
434
|
+
]
|
|
424
435
|
};
|
|
425
436
|
}
|
|
426
437
|
} else {
|
|
427
438
|
this.store.createdAtQuery = {
|
|
428
|
-
sales_time_between: [
|
|
439
|
+
sales_time_between: [
|
|
440
|
+
today.startOf("day").format("YYYY-MM-DD HH:mm:ss"),
|
|
441
|
+
today.endOf("day").format("YYYY-MM-DD HH:mm:ss")
|
|
442
|
+
]
|
|
429
443
|
};
|
|
430
444
|
}
|
|
431
445
|
} else {
|
|
432
|
-
// TODO: 这里后续可能需要使用店铺营业时间查询
|
|
433
446
|
this.store.createdAtQuery = {
|
|
434
|
-
sales_time_between: [today.startOf(
|
|
447
|
+
sales_time_between: [today.startOf("day").format("YYYY-MM-DD HH:mm:ss"), today.endOf("day").format("YYYY-MM-DD HH:mm:ss")]
|
|
435
448
|
};
|
|
436
449
|
}
|
|
437
450
|
}
|
|
@@ -441,36 +454,21 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
441
454
|
const raw = localStorage.getItem(ORDER_SYNC_THROTTLE_MS_STORAGE_KEY);
|
|
442
455
|
if (raw !== null) {
|
|
443
456
|
const parsed = Number(raw);
|
|
444
|
-
if (Number.isFinite(parsed) && parsed >= 0)
|
|
457
|
+
if (Number.isFinite(parsed) && parsed >= 0)
|
|
458
|
+
return parsed;
|
|
445
459
|
}
|
|
446
460
|
return DEFAULT_ORDER_SYNC_THROTTLE_MS;
|
|
447
461
|
}
|
|
448
462
|
async preload() {
|
|
449
|
-
// const hasPulledInCurrentWindow = this.hasPulledOrdersToday()
|
|
450
|
-
// // 仅当缓存属于当前统计窗口时才直接复用,避免跨天/跨营业日窗口继续使用旧数据
|
|
451
|
-
// if (cachedOrders.length > 0 && hasPulledInCurrentWindow) {
|
|
452
|
-
// this.store.list = cloneDeep(cachedOrders)
|
|
453
|
-
// this.syncOrdersMap()
|
|
454
|
-
// this.core.effects.emit(OrderHooks.onOrdersChanged, this.store.list)
|
|
455
|
-
// return
|
|
456
|
-
// }
|
|
457
|
-
|
|
458
|
-
// if (hasPulledInCurrentWindow) {
|
|
459
|
-
// this.logInfo('当天已完成全量订单拉取,跳过本次全量拉取', {
|
|
460
|
-
// lastFullFetchAt: this.getStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY),
|
|
461
|
-
// })
|
|
462
|
-
// return
|
|
463
|
-
// }
|
|
464
|
-
|
|
465
463
|
const getData = async () => {
|
|
466
464
|
const orders = await this.loadOrdersByServer();
|
|
467
465
|
if (orders.length === 0) {
|
|
468
466
|
return;
|
|
469
467
|
}
|
|
470
|
-
this.store.list = (0,
|
|
468
|
+
this.store.list = (0, import_lodash_es.cloneDeep)(orders);
|
|
471
469
|
this.syncOrdersMap();
|
|
472
|
-
this.emitOrdersChanged([],
|
|
473
|
-
this.core.effects.emit(
|
|
470
|
+
this.emitOrdersChanged([], "preload");
|
|
471
|
+
this.core.effects.emit(import_types.OrderHooks.onOrdersSyncCompleted, null);
|
|
474
472
|
};
|
|
475
473
|
getData();
|
|
476
474
|
}
|
|
@@ -480,7 +478,6 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
480
478
|
getOrderById(id) {
|
|
481
479
|
return this.store.map.get(this.getIdKey(id));
|
|
482
480
|
}
|
|
483
|
-
|
|
484
481
|
/** 按 order_id 查询内存订单。 */
|
|
485
482
|
getOrderByOrderId(orderId) {
|
|
486
483
|
return this.store.map.get(this.getIdKey(orderId));
|
|
@@ -488,28 +485,33 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
488
485
|
getLocalOrderFromMemoryByLookup(lookup) {
|
|
489
486
|
const key = this.getIdKey(lookup);
|
|
490
487
|
const memoryOrderById = this.store.map.get(key);
|
|
491
|
-
if (memoryOrderById)
|
|
492
|
-
|
|
488
|
+
if (memoryOrderById)
|
|
489
|
+
return memoryOrderById;
|
|
490
|
+
const memoryOrder = this.store.list.find((order) => this.isOrderLookupMatch(order, key));
|
|
493
491
|
return memoryOrder || null;
|
|
494
492
|
}
|
|
495
493
|
async getLocalOrderByLookup(lookup) {
|
|
496
494
|
const key = this.getIdKey(lookup);
|
|
497
495
|
const memoryOrderById = this.store.map.get(key);
|
|
498
|
-
if (memoryOrderById)
|
|
499
|
-
|
|
500
|
-
|
|
496
|
+
if (memoryOrderById)
|
|
497
|
+
return memoryOrderById;
|
|
498
|
+
const memoryOrder = this.store.list.find((order) => this.isOrderLookupMatch(order, key));
|
|
499
|
+
if (memoryOrder)
|
|
500
|
+
return memoryOrder;
|
|
501
501
|
const orders = await this.loadOrdersFromSQLite();
|
|
502
|
-
const localOrder = orders.find(order => this.isOrderLookupMatch(order, key));
|
|
503
|
-
if (!localOrder)
|
|
504
|
-
|
|
502
|
+
const localOrder = orders.find((order) => this.isOrderLookupMatch(order, key));
|
|
503
|
+
if (!localOrder)
|
|
504
|
+
return null;
|
|
505
|
+
this.store.list = orders.map((order) => this.normalizeOrderForMemoryList(order));
|
|
505
506
|
this.syncOrdersMap();
|
|
506
507
|
return this.normalizeOrderForMemoryList(localOrder);
|
|
507
508
|
}
|
|
508
509
|
async loadOrdersByServer() {
|
|
510
|
+
var _a;
|
|
509
511
|
let orderList = [];
|
|
510
|
-
this.logInfo(
|
|
512
|
+
this.logInfo("loadOrdersByServer-开始", {
|
|
511
513
|
hasOrderDataSource: !!this.orderDataSource,
|
|
512
|
-
query: this.store
|
|
514
|
+
query: ((_a = this.store) == null ? void 0 : _a.createdAtQuery) || null
|
|
513
515
|
});
|
|
514
516
|
if (this.orderDataSource) {
|
|
515
517
|
try {
|
|
@@ -519,25 +521,24 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
519
521
|
}
|
|
520
522
|
});
|
|
521
523
|
orderList = data || [];
|
|
522
|
-
this.logInfo(
|
|
524
|
+
this.logInfo("loadOrdersByServer-SSE拉取成功", {
|
|
523
525
|
count: orderList.length
|
|
524
526
|
});
|
|
525
527
|
this.markOrderPulledAtNow();
|
|
526
528
|
this.lastServerFullFetchAtMs = Date.now();
|
|
527
529
|
} catch {
|
|
528
|
-
this.logInfo(
|
|
530
|
+
this.logInfo("loadOrdersByServer-SSE拉取失败,保持当前内存订单");
|
|
529
531
|
return this.store.list;
|
|
530
532
|
}
|
|
531
533
|
}
|
|
532
|
-
const mergedOrders = await this.replaceOrdersSnapshotInSQLite(orderList,
|
|
533
|
-
const memoryOrders = mergedOrders.map(order => this.normalizeOrderForMemoryList(order));
|
|
534
|
-
this.logInfo(
|
|
534
|
+
const mergedOrders = await this.replaceOrdersSnapshotInSQLite(orderList, "loadOrdersByServer");
|
|
535
|
+
const memoryOrders = mergedOrders.map((order) => this.normalizeOrderForMemoryList(order));
|
|
536
|
+
this.logInfo("loadOrdersByServer-结束", {
|
|
535
537
|
count: memoryOrders.length
|
|
536
538
|
});
|
|
537
|
-
await this.core.effects.emit(
|
|
539
|
+
await this.core.effects.emit(import_types.OrderHooks.onOrdersLoaded, memoryOrders);
|
|
538
540
|
return memoryOrders;
|
|
539
541
|
}
|
|
540
|
-
|
|
541
542
|
/**
|
|
542
543
|
* 静默全量刷新:后台重新拉取全量 SSE 订单数据并更新本地
|
|
543
544
|
* 拿到完整数据后一次性替换 store,触发订单变更与同步完成事件
|
|
@@ -549,40 +550,39 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
549
550
|
if (this.lastServerFullFetchAtMs > 0 && elapsedSinceFullFetch < ORDER_SILENT_REFRESH_MIN_INTERVAL_MS) {
|
|
550
551
|
return this.store.list;
|
|
551
552
|
}
|
|
552
|
-
this.logInfo(
|
|
553
|
+
this.logInfo("silentRefresh 开始");
|
|
553
554
|
try {
|
|
554
|
-
// 刷新前,需要更新当前营业日边界(store.createdAtQuery)
|
|
555
555
|
this.updateCreateStore();
|
|
556
556
|
const orders = await this.loadOrdersByServer();
|
|
557
557
|
if (orders.length > 0) {
|
|
558
|
-
this.store.list = (0,
|
|
558
|
+
this.store.list = (0, import_lodash_es.cloneDeep)(orders);
|
|
559
559
|
this.syncOrdersMap();
|
|
560
|
-
this.emitOrdersChanged([],
|
|
561
|
-
await this.core.effects.emit(
|
|
562
|
-
this.logInfo(
|
|
560
|
+
this.emitOrdersChanged([], "silentRefresh");
|
|
561
|
+
await this.core.effects.emit(import_types.OrderHooks.onOrdersSyncCompleted, null);
|
|
562
|
+
this.logInfo("silentRefresh 完成", {
|
|
563
563
|
orderCount: orders.length,
|
|
564
564
|
duration: `${Date.now() - startTime}ms`
|
|
565
565
|
});
|
|
566
566
|
} else {
|
|
567
|
-
this.logInfo(
|
|
567
|
+
this.logInfo("silentRefresh: 服务器未返回数据");
|
|
568
568
|
}
|
|
569
569
|
return this.store.list;
|
|
570
570
|
} catch (error) {
|
|
571
571
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
572
|
-
this.logError(
|
|
572
|
+
this.logError("silentRefresh 失败", {
|
|
573
573
|
duration: `${Date.now() - startTime}ms`,
|
|
574
574
|
error: errorMessage
|
|
575
575
|
});
|
|
576
576
|
return this.store.list;
|
|
577
577
|
}
|
|
578
578
|
}
|
|
579
|
-
normalizeOrderForMemoryList(order, source =
|
|
579
|
+
normalizeOrderForMemoryList(order, source = "normalizeOrderForMemoryList") {
|
|
580
580
|
const normalizedOrder = this.normalizeOrderCollectionsForIngress(order, source);
|
|
581
|
-
const externalSaleNumber = normalizedOrder
|
|
582
|
-
if (normalizedOrder
|
|
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
583
|
return normalizedOrder;
|
|
584
584
|
}
|
|
585
|
-
if (externalSaleNumber ===
|
|
585
|
+
if (externalSaleNumber === void 0 || externalSaleNumber === null || externalSaleNumber === "") {
|
|
586
586
|
return normalizedOrder;
|
|
587
587
|
}
|
|
588
588
|
return {
|
|
@@ -590,202 +590,199 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
590
590
|
order_id: externalSaleNumber
|
|
591
591
|
};
|
|
592
592
|
}
|
|
593
|
-
|
|
594
593
|
/**
|
|
595
594
|
* 仅覆盖本地已存在的订单;不存在则直接跳过,不落库、不 emit。
|
|
596
595
|
* 适用于"按 order_id 主动刷新本地订单详情"的代理场景。
|
|
597
596
|
*/
|
|
598
597
|
async overwriteExistingOrder(fresh) {
|
|
599
|
-
const orderId = fresh
|
|
600
|
-
if (orderId ===
|
|
601
|
-
this.logError(
|
|
602
|
-
return {
|
|
603
|
-
overwritten: false
|
|
604
|
-
};
|
|
598
|
+
const orderId = fresh == null ? void 0 : fresh.order_id;
|
|
599
|
+
if (orderId === void 0 || orderId === null) {
|
|
600
|
+
this.logError("overwriteExistingOrder-入参缺少 order_id");
|
|
601
|
+
return { overwritten: false };
|
|
605
602
|
}
|
|
606
603
|
const key = this.getIdKey(orderId);
|
|
607
604
|
if (!this.store.map.has(key)) {
|
|
608
|
-
this.logInfo(
|
|
609
|
-
|
|
610
|
-
});
|
|
611
|
-
return {
|
|
612
|
-
overwritten: false
|
|
613
|
-
};
|
|
605
|
+
this.logInfo("overwriteExistingOrder-本地不存在该订单,跳过", { orderId });
|
|
606
|
+
return { overwritten: false };
|
|
614
607
|
}
|
|
615
|
-
this.logInfo(
|
|
608
|
+
this.logInfo("overwriteExistingOrder-开始覆盖", {
|
|
616
609
|
orderId,
|
|
617
610
|
storeOrderCountBefore: this.store.list.length
|
|
618
611
|
});
|
|
619
|
-
const normalizedFresh = this.normalizeOrderForMemoryList(
|
|
612
|
+
const normalizedFresh = this.normalizeOrderForMemoryList(
|
|
613
|
+
fresh,
|
|
614
|
+
"overwriteExistingOrder.incoming"
|
|
615
|
+
);
|
|
620
616
|
const existingOrder = this.store.map.get(key);
|
|
621
|
-
const reconciledFresh = this.reconcileOverwriteOrderCollections(
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
617
|
+
const reconciledFresh = this.reconcileOverwriteOrderCollections(
|
|
618
|
+
existingOrder,
|
|
619
|
+
normalizedFresh
|
|
620
|
+
);
|
|
621
|
+
this.store.list = this.store.list.map((order) => {
|
|
622
|
+
const id = order == null ? void 0 : order.order_id;
|
|
623
|
+
if (id === void 0 || id === null) {
|
|
624
|
+
return this.normalizeOrderForMemoryList(order, "overwriteExistingOrder.existingMemory");
|
|
626
625
|
}
|
|
627
|
-
return this.getIdKey(id) === key ? reconciledFresh : this.normalizeOrderForMemoryList(order,
|
|
626
|
+
return this.getIdKey(id) === key ? reconciledFresh : this.normalizeOrderForMemoryList(order, "overwriteExistingOrder.existingMemory");
|
|
628
627
|
});
|
|
629
628
|
this.syncOrdersMap();
|
|
630
|
-
await this.updateOrderInSQLite(reconciledFresh,
|
|
631
|
-
this.logInfo(
|
|
629
|
+
await this.updateOrderInSQLite(reconciledFresh, "overwriteExistingOrder");
|
|
630
|
+
this.logInfo("overwriteExistingOrder-结束", {
|
|
632
631
|
orderId,
|
|
633
632
|
storeOrderCountAfter: this.store.list.length
|
|
634
633
|
});
|
|
635
|
-
await this.emitOrdersChanged([reconciledFresh],
|
|
636
|
-
return {
|
|
637
|
-
overwritten: true
|
|
638
|
-
};
|
|
634
|
+
await this.emitOrdersChanged([reconciledFresh], "overwriteExistingOrder");
|
|
635
|
+
return { overwritten: true };
|
|
639
636
|
}
|
|
640
|
-
|
|
641
637
|
/**
|
|
642
638
|
* 将远端拉取的订单合并进本地 store(已存在则更新,不存在则追加),落库并 emit onOrdersChanged。
|
|
643
639
|
* 供 /update/localOrder 等在「本地尚无该单」时写入新建单。
|
|
644
640
|
*/
|
|
645
641
|
async upsertOrdersFromRemote(freshOrders) {
|
|
646
|
-
if (!freshOrders
|
|
647
|
-
this.logInfo(
|
|
642
|
+
if (!(freshOrders == null ? void 0 : freshOrders.length)) {
|
|
643
|
+
this.logInfo("upsertOrdersFromRemote-订单列表为空", {});
|
|
648
644
|
return;
|
|
649
645
|
}
|
|
650
|
-
this.logInfo(
|
|
651
|
-
|
|
652
|
-
});
|
|
653
|
-
await this.mergeOrdersToStore(freshOrders, 'upsertOrdersFromRemote');
|
|
646
|
+
this.logInfo("upsertOrdersFromRemote-开始", { count: freshOrders.length });
|
|
647
|
+
await this.mergeOrdersToStore(freshOrders, "upsertOrdersFromRemote");
|
|
654
648
|
}
|
|
655
649
|
async markOrderSyncedByExternalSaleNumber(params) {
|
|
656
650
|
const externalSaleNumber = params.externalSaleNumber;
|
|
657
|
-
if (externalSaleNumber ===
|
|
658
|
-
this.logError(
|
|
659
|
-
return {
|
|
660
|
-
updated: false
|
|
661
|
-
};
|
|
651
|
+
if (externalSaleNumber === void 0 || externalSaleNumber === null || externalSaleNumber === "") {
|
|
652
|
+
this.logError("markOrderSyncedByExternalSaleNumber-缺少 external_sale_number");
|
|
653
|
+
return { updated: false };
|
|
662
654
|
}
|
|
663
655
|
const key = this.getIdKey(externalSaleNumber);
|
|
664
|
-
const targetIndex = this.store.list.findIndex(order => {
|
|
665
|
-
const value = order
|
|
666
|
-
if (value ===
|
|
656
|
+
const targetIndex = this.store.list.findIndex((order) => {
|
|
657
|
+
const value = order == null ? void 0 : order.external_sale_number;
|
|
658
|
+
if (value === void 0 || value === null || value === "")
|
|
659
|
+
return false;
|
|
667
660
|
return this.getIdKey(value) === key;
|
|
668
661
|
});
|
|
669
662
|
if (targetIndex < 0) {
|
|
670
|
-
this.logInfo(
|
|
663
|
+
this.logInfo("markOrderSyncedByExternalSaleNumber-本地订单不存在,跳过", {
|
|
671
664
|
external_sale_number: externalSaleNumber
|
|
672
665
|
});
|
|
673
|
-
return {
|
|
674
|
-
updated: false
|
|
675
|
-
};
|
|
666
|
+
return { updated: false };
|
|
676
667
|
}
|
|
677
668
|
const existing = this.store.list[targetIndex];
|
|
678
669
|
const nextOrder = this.normalizeRemoteSyncedOrder({
|
|
679
670
|
...existing,
|
|
680
|
-
...
|
|
671
|
+
...params.patch || {},
|
|
681
672
|
external_sale_number: existing.external_sale_number ?? externalSaleNumber,
|
|
682
673
|
need_sync: 0
|
|
683
674
|
});
|
|
684
675
|
const storageKey = this.getOrderStorageKey(nextOrder) || key;
|
|
685
676
|
this.store.list = this.store.list.map((order, index) => {
|
|
686
|
-
if (index !== targetIndex)
|
|
677
|
+
if (index !== targetIndex)
|
|
678
|
+
return order;
|
|
687
679
|
return nextOrder;
|
|
688
680
|
});
|
|
689
681
|
this.syncOrdersMap();
|
|
690
|
-
await this.patchOrdersInSQLite(
|
|
691
|
-
[
|
|
692
|
-
|
|
693
|
-
|
|
682
|
+
await this.patchOrdersInSQLite(
|
|
683
|
+
[nextOrder],
|
|
684
|
+
"markOrderSyncedByExternalSaleNumber",
|
|
685
|
+
{ [storageKey]: "update" }
|
|
686
|
+
);
|
|
687
|
+
this.logInfo("markOrderSyncedByExternalSaleNumber-完成", {
|
|
694
688
|
external_sale_number: externalSaleNumber,
|
|
695
689
|
order_id: nextOrder.order_id ?? null
|
|
696
690
|
});
|
|
697
|
-
await this.emitOrdersChanged([nextOrder],
|
|
698
|
-
return {
|
|
699
|
-
updated: true,
|
|
700
|
-
order: nextOrder
|
|
701
|
-
};
|
|
691
|
+
await this.emitOrdersChanged([nextOrder], "markOrderSyncedByExternalSaleNumber");
|
|
692
|
+
return { updated: true, order: nextOrder };
|
|
702
693
|
}
|
|
703
|
-
|
|
704
694
|
/**
|
|
705
695
|
* 将本地待同步订单按 SQLite storage key 合并进 store 并落库。
|
|
706
696
|
* checkout 离线兜底可能没有 order_id,但通常会有 external_sale_number。
|
|
707
697
|
*/
|
|
708
698
|
async upsertPendingSyncOrders(pendingOrders) {
|
|
709
|
-
if (!pendingOrders
|
|
710
|
-
this.logInfo(
|
|
699
|
+
if (!(pendingOrders == null ? void 0 : pendingOrders.length)) {
|
|
700
|
+
this.logInfo("upsertPendingSyncOrders-订单列表为空", {});
|
|
711
701
|
return;
|
|
712
702
|
}
|
|
713
|
-
const pendingMap = new Map();
|
|
714
|
-
const memoryPendingMap = new Map();
|
|
703
|
+
const pendingMap = /* @__PURE__ */ new Map();
|
|
704
|
+
const memoryPendingMap = /* @__PURE__ */ new Map();
|
|
715
705
|
for (const order of pendingOrders) {
|
|
716
|
-
const normalizedOrder = this.normalizeOrderCollectionsForIngress(
|
|
706
|
+
const normalizedOrder = this.normalizeOrderCollectionsForIngress(
|
|
707
|
+
order,
|
|
708
|
+
"upsertPendingSyncOrders.incoming"
|
|
709
|
+
);
|
|
717
710
|
const storageKey = this.getOrderStorageKey(normalizedOrder);
|
|
718
|
-
if (!storageKey)
|
|
711
|
+
if (!storageKey)
|
|
712
|
+
continue;
|
|
719
713
|
pendingMap.set(storageKey, normalizedOrder);
|
|
720
|
-
memoryPendingMap.set(
|
|
714
|
+
memoryPendingMap.set(
|
|
715
|
+
storageKey,
|
|
716
|
+
this.normalizeOrderForMemoryList(
|
|
717
|
+
normalizedOrder,
|
|
718
|
+
"upsertPendingSyncOrders.memory"
|
|
719
|
+
)
|
|
720
|
+
);
|
|
721
721
|
}
|
|
722
722
|
if (pendingMap.size === 0) {
|
|
723
|
-
this.logError(
|
|
723
|
+
this.logError("upsertPendingSyncOrders-订单缺少可落库标识", {
|
|
724
724
|
count: pendingOrders.length
|
|
725
725
|
});
|
|
726
726
|
return;
|
|
727
727
|
}
|
|
728
|
-
this.logInfo(
|
|
729
|
-
count: pendingMap.size
|
|
730
|
-
});
|
|
728
|
+
this.logInfo("upsertPendingSyncOrders-开始", { count: pendingMap.size });
|
|
731
729
|
const mergeActions = {};
|
|
732
|
-
const updatedList = this.store.list.map(
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
const identityKeyToIndex = new Map();
|
|
730
|
+
const updatedList = this.store.list.map(
|
|
731
|
+
(order) => this.normalizeOrderForMemoryList(order, "upsertPendingSyncOrders.existingMemory")
|
|
732
|
+
);
|
|
733
|
+
const identityKeyToIndex = /* @__PURE__ */ new Map();
|
|
737
734
|
for (let index = 0; index < updatedList.length; index += 1) {
|
|
738
735
|
for (const key of this.getOrderIdentityMatchKeys(updatedList[index])) {
|
|
739
|
-
|
|
740
|
-
|
|
736
|
+
if (!identityKeyToIndex.has(key))
|
|
737
|
+
identityKeyToIndex.set(key, index);
|
|
741
738
|
}
|
|
742
739
|
}
|
|
743
740
|
for (const [storageKey, pendingOrder] of memoryPendingMap.entries()) {
|
|
744
|
-
const matchIndex = this.lookupOrderIndexByIdentityKeys(
|
|
741
|
+
const matchIndex = this.lookupOrderIndexByIdentityKeys(
|
|
742
|
+
identityKeyToIndex,
|
|
743
|
+
this.getOrderIdentityMatchKeys(pendingOrder)
|
|
744
|
+
);
|
|
745
745
|
if (matchIndex >= 0) {
|
|
746
746
|
const existingOrder = updatedList[matchIndex];
|
|
747
747
|
const mergedOrder = this.mergeOrderRecords(existingOrder, pendingOrder);
|
|
748
748
|
updatedList[matchIndex] = mergedOrder;
|
|
749
749
|
const pendingSnapshot = pendingMap.get(storageKey);
|
|
750
750
|
if (pendingSnapshot) {
|
|
751
|
-
pendingMap.set(
|
|
751
|
+
pendingMap.set(
|
|
752
|
+
storageKey,
|
|
753
|
+
this.reconcileOverwriteOrderCollections(existingOrder, pendingSnapshot)
|
|
754
|
+
);
|
|
752
755
|
}
|
|
753
|
-
// 合并后身份字段可能新增(如挂单拿到 order_id),同步登记,供同批后续 pending 命中同一槽位
|
|
754
756
|
this.registerOrderIdentityKeys(identityKeyToIndex, mergedOrder, matchIndex);
|
|
755
|
-
mergeActions[storageKey] =
|
|
757
|
+
mergeActions[storageKey] = "update";
|
|
756
758
|
continue;
|
|
757
759
|
}
|
|
758
760
|
const insertIndex = updatedList.length;
|
|
759
761
|
updatedList.push(pendingOrder);
|
|
760
762
|
this.registerOrderIdentityKeys(identityKeyToIndex, pendingOrder, insertIndex);
|
|
761
|
-
mergeActions[storageKey] =
|
|
763
|
+
mergeActions[storageKey] = "insert";
|
|
762
764
|
}
|
|
763
765
|
const patchedOrders = [...pendingMap.values()];
|
|
764
|
-
|
|
765
|
-
this.store.list = this.runOrderStoreSelfCheck(updatedList, 'upsertPendingSyncOrders.store');
|
|
766
|
+
this.store.list = this.runOrderStoreSelfCheck(updatedList, "upsertPendingSyncOrders.store");
|
|
766
767
|
this.syncOrdersMap();
|
|
767
|
-
await this.patchOrdersInSQLite(patchedOrders,
|
|
768
|
-
this.logInfo(
|
|
768
|
+
await this.patchOrdersInSQLite(patchedOrders, "upsertPendingSyncOrders", mergeActions);
|
|
769
|
+
this.logInfo("upsertPendingSyncOrders-结束", {
|
|
769
770
|
count: patchedOrders.length,
|
|
770
771
|
storeOrderCountAfter: this.store.list.length
|
|
771
772
|
});
|
|
772
|
-
await this.emitOrdersChanged(patchedOrders,
|
|
773
|
+
await this.emitOrdersChanged(patchedOrders, "upsertPendingSyncOrders");
|
|
773
774
|
}
|
|
774
|
-
|
|
775
775
|
/**
|
|
776
776
|
* 通过 SSE 按自定义 query 拉取订单(支持 select/with 精简字段)
|
|
777
777
|
*/
|
|
778
778
|
async fetchOrdersBySSE(query = {}) {
|
|
779
|
-
if (!this.orderDataSource)
|
|
779
|
+
if (!this.orderDataSource)
|
|
780
|
+
return [];
|
|
780
781
|
try {
|
|
781
|
-
const data = await this.orderDataSource.run({
|
|
782
|
-
sse: {
|
|
783
|
-
query
|
|
784
|
-
}
|
|
785
|
-
});
|
|
782
|
+
const data = await this.orderDataSource.run({ sse: { query } });
|
|
786
783
|
return data || [];
|
|
787
784
|
} catch (error) {
|
|
788
|
-
this.logError(
|
|
785
|
+
this.logError("fetchOrdersBySSE-失败", {
|
|
789
786
|
error: error instanceof Error ? error.message : String(error)
|
|
790
787
|
});
|
|
791
788
|
return [];
|
|
@@ -795,25 +792,29 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
795
792
|
return [];
|
|
796
793
|
}
|
|
797
794
|
destroy() {
|
|
795
|
+
var _a;
|
|
798
796
|
if (this.syncTimer) {
|
|
799
797
|
clearTimeout(this.syncTimer);
|
|
800
|
-
this.syncTimer =
|
|
798
|
+
this.syncTimer = void 0;
|
|
801
799
|
}
|
|
802
800
|
this.isProcessingSyncBatch = false;
|
|
803
801
|
this.pendingSyncMessages = [];
|
|
804
|
-
if (this.orderDataSource
|
|
802
|
+
if ((_a = this.orderDataSource) == null ? void 0 : _a.destroy)
|
|
803
|
+
this.orderDataSource.destroy();
|
|
805
804
|
super.destroy();
|
|
806
805
|
}
|
|
807
806
|
syncOrdersMap() {
|
|
808
807
|
this.store.map.clear();
|
|
809
808
|
for (const order of this.store.list) {
|
|
810
809
|
const primaryIdentity = this.getOrderMapKey(order);
|
|
811
|
-
if (!primaryIdentity)
|
|
810
|
+
if (!primaryIdentity)
|
|
811
|
+
continue;
|
|
812
812
|
this.store.map.set(primaryIdentity, order);
|
|
813
813
|
}
|
|
814
814
|
}
|
|
815
815
|
getOrderMapKey(order) {
|
|
816
|
-
if (!order)
|
|
816
|
+
if (!order)
|
|
817
|
+
return "";
|
|
817
818
|
if (!this.isBlankIdentityValue(order.order_id)) {
|
|
818
819
|
return this.getIdKey(order.order_id);
|
|
819
820
|
}
|
|
@@ -821,82 +822,88 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
821
822
|
if (!this.isBlankIdentityValue(externalSaleNumber)) {
|
|
822
823
|
return this.getIdKey(externalSaleNumber);
|
|
823
824
|
}
|
|
824
|
-
return
|
|
825
|
+
return "";
|
|
825
826
|
}
|
|
826
827
|
isBlankIdentityValue(value) {
|
|
827
|
-
return value ===
|
|
828
|
+
return value === void 0 || value === null || value === "";
|
|
828
829
|
}
|
|
829
830
|
getOrderIdentityEntries(order) {
|
|
830
|
-
if (!order)
|
|
831
|
+
if (!order)
|
|
832
|
+
return [];
|
|
831
833
|
const record = order;
|
|
832
|
-
const candidates = [
|
|
833
|
-
field:
|
|
834
|
-
value:
|
|
835
|
-
|
|
836
|
-
field:
|
|
837
|
-
|
|
838
|
-
}, {
|
|
839
|
-
field: 'order_number',
|
|
840
|
-
value: record.order_number
|
|
841
|
-
}, {
|
|
842
|
-
field: 'shop_order_number',
|
|
843
|
-
value: record.shop_order_number
|
|
844
|
-
}];
|
|
834
|
+
const candidates = [
|
|
835
|
+
{ field: "order_id", value: order.order_id },
|
|
836
|
+
{ field: "external_sale_number", value: record.external_sale_number },
|
|
837
|
+
{ field: "order_number", value: record.order_number },
|
|
838
|
+
{ field: "shop_order_number", value: record.shop_order_number }
|
|
839
|
+
];
|
|
845
840
|
const entries = [];
|
|
846
841
|
for (const candidate of candidates) {
|
|
847
|
-
if (this.isBlankIdentityValue(candidate.value))
|
|
842
|
+
if (this.isBlankIdentityValue(candidate.value))
|
|
843
|
+
continue;
|
|
848
844
|
const key = this.getIdKey(candidate.value);
|
|
849
|
-
if (entries.some(entry => entry.field === candidate.field && entry.key === key))
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
key
|
|
853
|
-
});
|
|
845
|
+
if (entries.some((entry) => entry.field === candidate.field && entry.key === key))
|
|
846
|
+
continue;
|
|
847
|
+
entries.push({ field: candidate.field, key });
|
|
854
848
|
}
|
|
855
849
|
return entries;
|
|
856
850
|
}
|
|
857
851
|
getOrderIdentityKeys(order) {
|
|
858
852
|
const keys = [];
|
|
859
853
|
for (const entry of this.getOrderIdentityEntries(order)) {
|
|
860
|
-
if (!keys.includes(entry.key))
|
|
854
|
+
if (!keys.includes(entry.key))
|
|
855
|
+
keys.push(entry.key);
|
|
861
856
|
}
|
|
862
857
|
return keys;
|
|
863
858
|
}
|
|
864
859
|
getOrderDateKey(order) {
|
|
865
|
-
|
|
860
|
+
var _a, _b, _c, _d;
|
|
861
|
+
const candidates = [
|
|
862
|
+
order == null ? void 0 : order.schedule_date,
|
|
863
|
+
order == null ? void 0 : order.create_date,
|
|
864
|
+
order == null ? void 0 : order.created_at,
|
|
865
|
+
(_b = (_a = order == null ? void 0 : order.bookings) == null ? void 0 : _a[0]) == null ? void 0 : _b.start_date,
|
|
866
|
+
(_d = (_c = order == null ? void 0 : order.bookings) == null ? void 0 : _c[0]) == null ? void 0 : _d.select_date
|
|
867
|
+
];
|
|
866
868
|
for (const v of candidates) {
|
|
867
|
-
if (!v)
|
|
869
|
+
if (!v)
|
|
870
|
+
continue;
|
|
868
871
|
const text = String(v);
|
|
869
|
-
if (!text)
|
|
870
|
-
|
|
872
|
+
if (!text)
|
|
873
|
+
continue;
|
|
874
|
+
return text.split("T")[0].split(" ")[0];
|
|
871
875
|
}
|
|
872
|
-
return
|
|
876
|
+
return void 0;
|
|
873
877
|
}
|
|
874
|
-
|
|
875
878
|
/**
|
|
876
879
|
* 初始化 OrderDataSource 实例
|
|
877
880
|
*/
|
|
878
881
|
initOrderDataSource() {
|
|
879
|
-
|
|
880
|
-
|
|
882
|
+
var _a, _b;
|
|
883
|
+
const OrderDataSourceClass = (_b = (_a = this.core.serverOptions) == null ? void 0 : _a.All_DATA_SOURCES) == null ? void 0 : _b.OrderDataSource;
|
|
884
|
+
if (!OrderDataSourceClass)
|
|
885
|
+
return;
|
|
881
886
|
this.orderDataSource = new OrderDataSourceClass();
|
|
882
887
|
}
|
|
883
|
-
|
|
884
888
|
/**
|
|
885
889
|
* 初始化 pubsub 订阅,监听订单变更(纯订阅,不拉数据;全量 SSE 由 loadOrdersByServer 负责)
|
|
886
890
|
*/
|
|
887
891
|
setupOrderSync() {
|
|
888
|
-
if (!this.orderDataSource)
|
|
892
|
+
if (!this.orderDataSource)
|
|
893
|
+
return;
|
|
889
894
|
this.orderDataSource.run({
|
|
890
895
|
pubsub: {
|
|
891
|
-
callback: res => {
|
|
896
|
+
callback: (res) => {
|
|
897
|
+
console.log("orderDataSource", res);
|
|
892
898
|
const pubsubReceivedAt = Date.now();
|
|
893
899
|
const message = this.normalizeOrderSyncMessage(res);
|
|
894
|
-
if (!message)
|
|
900
|
+
if (!message)
|
|
901
|
+
return;
|
|
895
902
|
message._pubsubReceivedAt = pubsubReceivedAt;
|
|
896
903
|
this.pendingSyncMessages.push(message);
|
|
897
904
|
const throttleMs = this.getOrderSyncThrottleMs();
|
|
898
905
|
const routeInfo = this.resolveSyncMessageRoute(message);
|
|
899
|
-
this.logInfo(
|
|
906
|
+
this.logInfo("orderSync-收到消息并入队", {
|
|
900
907
|
id: message.id ?? null,
|
|
901
908
|
order_id: message.order_id ?? null,
|
|
902
909
|
type: message.type ?? null,
|
|
@@ -909,10 +916,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
909
916
|
}
|
|
910
917
|
}
|
|
911
918
|
}).catch(() => {
|
|
912
|
-
// 忽略同步初始化异常,避免影响主流程
|
|
913
919
|
});
|
|
914
920
|
}
|
|
915
|
-
|
|
916
921
|
/**
|
|
917
922
|
* 调度订单同步节流窗口(leading-edge throttle):
|
|
918
923
|
* - 空闲状态下收到的第一条消息立即触发批处理,无需等待;
|
|
@@ -920,27 +925,29 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
920
925
|
* - 若当前批处理执行中,则由批处理结束后决定是否开启下一轮窗口。
|
|
921
926
|
*/
|
|
922
927
|
scheduleOrderSyncThrottle() {
|
|
923
|
-
if (this.isProcessingSyncBatch)
|
|
928
|
+
if (this.isProcessingSyncBatch)
|
|
929
|
+
return;
|
|
924
930
|
if (this.isIdlePhase) {
|
|
925
931
|
this.isIdlePhase = false;
|
|
926
|
-
this.logInfo(
|
|
932
|
+
this.logInfo("orderSync-首条消息立即触发处理");
|
|
927
933
|
void this.flushOrderSyncMessagesByThrottle();
|
|
928
934
|
return;
|
|
929
935
|
}
|
|
930
|
-
if (this.syncTimer)
|
|
936
|
+
if (this.syncTimer)
|
|
937
|
+
return;
|
|
931
938
|
const throttleMs = this.getOrderSyncThrottleMs();
|
|
932
939
|
this.syncTimer = setTimeout(() => {
|
|
933
|
-
this.syncTimer =
|
|
940
|
+
this.syncTimer = void 0;
|
|
934
941
|
void this.flushOrderSyncMessagesByThrottle();
|
|
935
942
|
}, throttleMs);
|
|
936
943
|
}
|
|
937
|
-
|
|
938
944
|
/**
|
|
939
945
|
* 执行一次节流批处理并在需要时续约下一轮窗口。
|
|
940
946
|
* 批处理完成且无后续消息时恢复空闲状态,下一条消息将立即触发。
|
|
941
947
|
*/
|
|
942
948
|
async flushOrderSyncMessagesByThrottle() {
|
|
943
|
-
if (this.isProcessingSyncBatch)
|
|
949
|
+
if (this.isProcessingSyncBatch)
|
|
950
|
+
return;
|
|
944
951
|
if (this.pendingSyncMessages.length === 0) {
|
|
945
952
|
this.isIdlePhase = true;
|
|
946
953
|
return;
|
|
@@ -957,7 +964,6 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
957
964
|
}
|
|
958
965
|
}
|
|
959
966
|
}
|
|
960
|
-
|
|
961
967
|
/**
|
|
962
968
|
* 处理节流窗口内聚合后的同步消息批次
|
|
963
969
|
*
|
|
@@ -972,16 +978,19 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
972
978
|
async processOrderSyncMessages() {
|
|
973
979
|
const messages = [...this.pendingSyncMessages];
|
|
974
980
|
this.pendingSyncMessages = [];
|
|
975
|
-
if (messages.length === 0)
|
|
981
|
+
if (messages.length === 0)
|
|
982
|
+
return;
|
|
976
983
|
const batchProcessStartAt = Date.now();
|
|
977
|
-
const earliestReceivedAt = Math.min(
|
|
978
|
-
|
|
984
|
+
const earliestReceivedAt = Math.min(
|
|
985
|
+
...messages.map((m) => m._pubsubReceivedAt ?? batchProcessStartAt)
|
|
986
|
+
);
|
|
987
|
+
this.logInfo("processOrderSyncMessages-开始", {
|
|
979
988
|
messageCount: messages.length,
|
|
980
989
|
earliestReceivedAt: new Date(earliestReceivedAt).toISOString(),
|
|
981
990
|
batchProcessStartAt: new Date(batchProcessStartAt).toISOString(),
|
|
982
991
|
waitDurationMs: batchProcessStartAt - earliestReceivedAt
|
|
983
992
|
});
|
|
984
|
-
const upsertOrders = new Map();
|
|
993
|
+
const upsertOrders = /* @__PURE__ */ new Map();
|
|
985
994
|
const refreshIds = [];
|
|
986
995
|
messages.forEach((msg, msgIndex) => {
|
|
987
996
|
const routeInfo = this.resolveSyncMessageRoute(msg);
|
|
@@ -989,47 +998,50 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
989
998
|
const singleId = routeInfo.singleId;
|
|
990
999
|
const hasSingleId = routeInfo.hasSingleId;
|
|
991
1000
|
const normalizedBody = this.normalizeOrderSyncPayload(msg.body || msg.data);
|
|
992
|
-
if (routeInfo.route ===
|
|
1001
|
+
if (routeInfo.route === "bodyUpsert" && normalizedBody) {
|
|
993
1002
|
upsertOrders.set(this.getIdKey(normalizedBody.order_id), normalizedBody);
|
|
994
1003
|
return;
|
|
995
1004
|
}
|
|
996
|
-
if (hasBatchIds)
|
|
1005
|
+
if (hasBatchIds)
|
|
1006
|
+
refreshIds.push(...routeInfo.batchIds);
|
|
1007
|
+
else if (routeInfo.route === "httpRefresh.singleId" && singleId !== null)
|
|
1008
|
+
refreshIds.push(singleId);
|
|
1009
|
+
else if (routeInfo.route === "httpRefresh.relationIds")
|
|
1010
|
+
refreshIds.push(...routeInfo.batchIds);
|
|
997
1011
|
});
|
|
998
1012
|
const uniqueRefreshIds = this.uniqueOrderIds(refreshIds);
|
|
999
1013
|
const upsertList = [...upsertOrders.values()];
|
|
1000
|
-
this.logInfo(
|
|
1014
|
+
this.logInfo("processOrderSyncMessages-去重完成", {
|
|
1001
1015
|
upsertCount: upsertList.length,
|
|
1002
1016
|
refreshIdCount: uniqueRefreshIds.length
|
|
1003
1017
|
});
|
|
1004
1018
|
if (upsertList.length > 0) {
|
|
1005
|
-
await this.mergeOrdersToStore(upsertList,
|
|
1019
|
+
await this.mergeOrdersToStore(upsertList, "pubsub.bodyUpsert");
|
|
1006
1020
|
}
|
|
1007
1021
|
if (uniqueRefreshIds.length > 0) {
|
|
1008
|
-
const {
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
} = this.filterRedundantHttpRefreshIds(uniqueRefreshIds);
|
|
1012
|
-
if (skipped.length > 0) {}
|
|
1022
|
+
const { toFetch, skipped } = this.filterRedundantHttpRefreshIds(uniqueRefreshIds);
|
|
1023
|
+
if (skipped.length > 0) {
|
|
1024
|
+
}
|
|
1013
1025
|
if (toFetch.length > 0) {
|
|
1014
1026
|
const freshOrders = await this.fetchOrdersByHttp(toFetch);
|
|
1015
1027
|
if (freshOrders.length > 0) {
|
|
1016
|
-
await this.mergeOrdersToStore(freshOrders,
|
|
1017
|
-
} else {
|
|
1028
|
+
await this.mergeOrdersToStore(freshOrders, "pubsub.httpRefresh");
|
|
1029
|
+
} else {
|
|
1030
|
+
}
|
|
1018
1031
|
}
|
|
1019
1032
|
}
|
|
1020
1033
|
if (upsertList.length === 0 && uniqueRefreshIds.length === 0) {
|
|
1021
1034
|
return;
|
|
1022
1035
|
}
|
|
1023
1036
|
const batchProcessEndAt = Date.now();
|
|
1024
|
-
this.logInfo(
|
|
1037
|
+
this.logInfo("processOrderSyncMessages-结束", {
|
|
1025
1038
|
upsertCount: upsertList.length,
|
|
1026
1039
|
refreshIdCount: uniqueRefreshIds.length,
|
|
1027
1040
|
batchProcessDurationMs: batchProcessEndAt - batchProcessStartAt,
|
|
1028
1041
|
totalFromPubsubToProcessedMs: batchProcessEndAt - earliestReceivedAt
|
|
1029
1042
|
});
|
|
1030
|
-
await this.core.effects.emit(
|
|
1043
|
+
await this.core.effects.emit(import_types.OrderHooks.onOrdersSyncCompleted, null);
|
|
1031
1044
|
}
|
|
1032
|
-
|
|
1033
1045
|
/**
|
|
1034
1046
|
* 通过 HTTP 按 ids 批量拉取订单详情(走 orderDataSource)。
|
|
1035
1047
|
*
|
|
@@ -1041,17 +1053,16 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1041
1053
|
* const fresh = await orderModule.fetchOrdersByHttp(['96971', '96972'])
|
|
1042
1054
|
*/
|
|
1043
1055
|
async fetchOrdersByHttp(ids) {
|
|
1044
|
-
if (!this.orderDataSource || ids.length === 0)
|
|
1056
|
+
if (!this.orderDataSource || ids.length === 0)
|
|
1057
|
+
return [];
|
|
1045
1058
|
try {
|
|
1046
|
-
if (typeof this.orderDataSource.fetchOrdersByIds ===
|
|
1047
|
-
const
|
|
1048
|
-
return
|
|
1059
|
+
if (typeof this.orderDataSource.fetchOrdersByIds === "function") {
|
|
1060
|
+
const orderList2 = await this.orderDataSource.fetchOrdersByIds(ids);
|
|
1061
|
+
return orderList2 || [];
|
|
1049
1062
|
}
|
|
1050
1063
|
const orderList = await this.orderDataSource.run({
|
|
1051
1064
|
http: {
|
|
1052
|
-
query: {
|
|
1053
|
-
ids
|
|
1054
|
-
}
|
|
1065
|
+
query: { ids }
|
|
1055
1066
|
}
|
|
1056
1067
|
});
|
|
1057
1068
|
return orderList || [];
|
|
@@ -1059,13 +1070,12 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1059
1070
|
return [];
|
|
1060
1071
|
}
|
|
1061
1072
|
}
|
|
1062
|
-
|
|
1063
1073
|
/**
|
|
1064
1074
|
* 将增量订单合并到 store
|
|
1065
1075
|
*/
|
|
1066
1076
|
async mergeOrdersToStore(freshOrders, source) {
|
|
1067
1077
|
const storeOrderCountBefore = this.store.list.length;
|
|
1068
|
-
this.logInfo(
|
|
1078
|
+
this.logInfo("mergeOrdersToStore-开始", {
|
|
1069
1079
|
freshOrderCount: freshOrders.length,
|
|
1070
1080
|
storeOrderCountBefore,
|
|
1071
1081
|
source
|
|
@@ -1073,37 +1083,38 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1073
1083
|
this.logDuplicateOrders(`${source}.beforeMerge`, this.store.list);
|
|
1074
1084
|
const normalizedFreshOrders = [];
|
|
1075
1085
|
for (const order of freshOrders) {
|
|
1076
|
-
const id = order
|
|
1077
|
-
if (id ===
|
|
1086
|
+
const id = order == null ? void 0 : order.order_id;
|
|
1087
|
+
if (id === void 0 || id === null)
|
|
1088
|
+
continue;
|
|
1078
1089
|
normalizedFreshOrders.push(this.normalizeRemoteSyncedOrder(order));
|
|
1079
1090
|
}
|
|
1080
|
-
|
|
1081
|
-
|
|
1091
|
+
const uniqueFreshOrders = this.compactOrderListByIdentity(
|
|
1092
|
+
normalizedFreshOrders,
|
|
1093
|
+
`${source}.incoming`
|
|
1094
|
+
).list;
|
|
1082
1095
|
const uniqueFreshCount = uniqueFreshOrders.length;
|
|
1083
1096
|
const patchedOrders = [];
|
|
1084
1097
|
const mergeActions = {};
|
|
1085
|
-
const updatedList = this.store.list.map(
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
// 任一身份字段(order_id/external_sale_number/order_number/shop_order_number)同值即同一单。
|
|
1090
|
-
const identityKeyToIndex = new Map();
|
|
1098
|
+
const updatedList = this.store.list.map(
|
|
1099
|
+
(order) => this.normalizeOrderForMemoryList(order, `${source}.existingMemory`)
|
|
1100
|
+
);
|
|
1101
|
+
const identityKeyToIndex = /* @__PURE__ */ new Map();
|
|
1091
1102
|
for (let index = 0; index < updatedList.length; index += 1) {
|
|
1092
1103
|
const identityKeys = this.getOrderIdentityMatchKeys(updatedList[index]);
|
|
1093
1104
|
for (const key of identityKeys) {
|
|
1094
|
-
|
|
1095
|
-
|
|
1105
|
+
if (!identityKeyToIndex.has(key))
|
|
1106
|
+
identityKeyToIndex.set(key, index);
|
|
1096
1107
|
}
|
|
1097
1108
|
}
|
|
1098
1109
|
for (const fresh of uniqueFreshOrders) {
|
|
1099
1110
|
const freshIdentityKeys = this.getOrderIdentityMatchKeys(fresh);
|
|
1100
1111
|
const matchIndex = this.lookupOrderIndexByIdentityKeys(identityKeyToIndex, freshIdentityKeys);
|
|
1101
1112
|
const storageKey = this.getOrderStorageKey(fresh);
|
|
1102
|
-
const mergeKey = storageKey || (fresh.order_id !==
|
|
1113
|
+
const mergeKey = storageKey || (fresh.order_id !== void 0 && fresh.order_id !== null ? this.getIdKey(fresh.order_id) : "");
|
|
1103
1114
|
if (matchIndex >= 0) {
|
|
1104
1115
|
const existingOrder = updatedList[matchIndex];
|
|
1105
1116
|
if (this.isPendingSyncOrder(existingOrder) && this.isRemoteEchoMergeSource(source)) {
|
|
1106
|
-
this.logInfo(
|
|
1117
|
+
this.logInfo("mergeOrdersToStore-跳过 pending 订单远端覆盖", {
|
|
1107
1118
|
source,
|
|
1108
1119
|
order_id: existingOrder.order_id ?? fresh.order_id ?? null,
|
|
1109
1120
|
external_sale_number: existingOrder.external_sale_number ?? fresh.external_sale_number ?? null,
|
|
@@ -1111,38 +1122,36 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1111
1122
|
remote_payment_status: fresh.payment_status ?? null,
|
|
1112
1123
|
local_need_sync: existingOrder.need_sync ?? null,
|
|
1113
1124
|
remote_need_sync: fresh.need_sync ?? null,
|
|
1114
|
-
reason:
|
|
1125
|
+
reason: "protect_pending_sync_order_from_remote_echo"
|
|
1115
1126
|
});
|
|
1116
1127
|
continue;
|
|
1117
1128
|
}
|
|
1118
1129
|
const mergedOrder = this.mergeOrderRecords(existingOrder, fresh);
|
|
1119
1130
|
updatedList[matchIndex] = mergedOrder;
|
|
1120
|
-
// 合并后身份字段可能新增(如挂单拿到 order_id),同步登记到索引,
|
|
1121
|
-
// 供同批后续 fresh 命中同一槽位,避免重复插入
|
|
1122
1131
|
this.registerOrderIdentityKeys(identityKeyToIndex, mergedOrder, matchIndex);
|
|
1123
1132
|
patchedOrders.push(mergedOrder);
|
|
1124
|
-
if (mergeKey)
|
|
1133
|
+
if (mergeKey)
|
|
1134
|
+
mergeActions[mergeKey] = "update";
|
|
1125
1135
|
continue;
|
|
1126
1136
|
}
|
|
1127
1137
|
const insertIndex = updatedList.length;
|
|
1128
1138
|
updatedList.push(fresh);
|
|
1129
1139
|
this.registerOrderIdentityKeys(identityKeyToIndex, fresh, insertIndex);
|
|
1130
1140
|
patchedOrders.push(fresh);
|
|
1131
|
-
if (mergeKey)
|
|
1141
|
+
if (mergeKey)
|
|
1142
|
+
mergeActions[mergeKey] = "insert";
|
|
1132
1143
|
}
|
|
1133
|
-
const insertCount = Object.values(mergeActions).filter(v => v ===
|
|
1134
|
-
const updateCount = Object.values(mergeActions).filter(v => v ===
|
|
1135
|
-
this.logInfo(
|
|
1144
|
+
const insertCount = Object.values(mergeActions).filter((v) => v === "insert").length;
|
|
1145
|
+
const updateCount = Object.values(mergeActions).filter((v) => v === "update").length;
|
|
1146
|
+
this.logInfo("mergeOrdersToStore-合并完成", {
|
|
1136
1147
|
insertCount,
|
|
1137
1148
|
updateCount,
|
|
1138
1149
|
storeOrderCountAfter: this.store.list.length
|
|
1139
1150
|
});
|
|
1140
|
-
// 增量索引已保证 store 去重不变量,无需再对全表做 O(n^2) 压缩;
|
|
1141
|
-
// 仅在自检开关开启时做一次兜底校验。
|
|
1142
1151
|
this.store.list = this.runOrderStoreSelfCheck(updatedList, `${source}.store`);
|
|
1143
1152
|
this.syncOrdersMap();
|
|
1144
1153
|
await this.patchOrdersInSQLite(patchedOrders, source, mergeActions);
|
|
1145
|
-
this.logInfo(
|
|
1154
|
+
this.logInfo("mergeOrdersToStore-结束", {
|
|
1146
1155
|
uniqueFreshCount,
|
|
1147
1156
|
storeOrderCountAfter: this.store.list.length,
|
|
1148
1157
|
insertCount,
|
|
@@ -1150,7 +1159,6 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1150
1159
|
});
|
|
1151
1160
|
await this.emitOrdersChanged(patchedOrders, source);
|
|
1152
1161
|
}
|
|
1153
|
-
|
|
1154
1162
|
/**
|
|
1155
1163
|
* 在身份索引中查找与目标订单共享任一身份键的已存在订单下标。
|
|
1156
1164
|
* 返回所有命中键里最小的下标,等价于原 findOrderIndexByIdentity 的「取首个匹配」语义。
|
|
@@ -1162,15 +1170,16 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1162
1170
|
let matchIndex = -1;
|
|
1163
1171
|
for (const key of identityKeys) {
|
|
1164
1172
|
const index = identityKeyToIndex.get(key);
|
|
1165
|
-
if (index ===
|
|
1166
|
-
|
|
1173
|
+
if (index === void 0)
|
|
1174
|
+
continue;
|
|
1175
|
+
if (matchIndex < 0 || index < matchIndex)
|
|
1176
|
+
matchIndex = index;
|
|
1167
1177
|
}
|
|
1168
1178
|
return matchIndex;
|
|
1169
1179
|
}
|
|
1170
1180
|
isRemoteEchoMergeSource(source) {
|
|
1171
|
-
return source ===
|
|
1181
|
+
return source === "pubsub.bodyUpsert" || source === "pubsub.httpRefresh";
|
|
1172
1182
|
}
|
|
1173
|
-
|
|
1174
1183
|
/**
|
|
1175
1184
|
* 将订单的全部身份键登记到索引并指向其在列表中的下标。
|
|
1176
1185
|
* 合并后订单新增的身份字段(如挂单同步后拿到 order_id)也会被登记。
|
|
@@ -1184,53 +1193,54 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1184
1193
|
identityKeyToIndex.set(key, index);
|
|
1185
1194
|
}
|
|
1186
1195
|
}
|
|
1187
|
-
|
|
1188
1196
|
/**
|
|
1189
1197
|
* 合并热路径去重兜底:默认直接返回原列表(增量索引已保证无重复)。
|
|
1190
1198
|
* 仅当 ORDER_MERGE_SELF_CHECK 开启时,额外做一次全表压缩并在发现残留重复时告警。
|
|
1191
1199
|
*/
|
|
1192
1200
|
runOrderStoreSelfCheck(orders, source) {
|
|
1193
|
-
if (!ORDER_MERGE_SELF_CHECK)
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
removedCount
|
|
1197
|
-
} = this.compactOrderListByIdentity(orders, source);
|
|
1201
|
+
if (!ORDER_MERGE_SELF_CHECK)
|
|
1202
|
+
return orders;
|
|
1203
|
+
const { list, removedCount } = this.compactOrderListByIdentity(orders, source);
|
|
1198
1204
|
if (removedCount > 0) {
|
|
1199
|
-
this.logWarning(
|
|
1200
|
-
source,
|
|
1201
|
-
removedCount
|
|
1202
|
-
});
|
|
1205
|
+
this.logWarning("合并自检发现残留重复订单,已压缩", { source, removedCount });
|
|
1203
1206
|
}
|
|
1204
1207
|
return list;
|
|
1205
1208
|
}
|
|
1206
1209
|
normalizeOrderSyncMessage(res) {
|
|
1207
|
-
const data = res
|
|
1208
|
-
if (!data)
|
|
1209
|
-
|
|
1210
|
+
const data = (res == null ? void 0 : res.data) || res;
|
|
1211
|
+
if (!data)
|
|
1212
|
+
return null;
|
|
1213
|
+
const payload = (data == null ? void 0 : data.data) && typeof data.data === "object" ? data.data : void 0;
|
|
1210
1214
|
const normalized = {
|
|
1211
1215
|
...data,
|
|
1212
|
-
_channelKey: data.module ||
|
|
1216
|
+
_channelKey: data.module || "sales_sync"
|
|
1213
1217
|
};
|
|
1214
|
-
if (!normalized.type && typeof data.event ===
|
|
1215
|
-
|
|
1216
|
-
if (!normalized.id && data.
|
|
1217
|
-
|
|
1218
|
-
if (!normalized.
|
|
1219
|
-
|
|
1220
|
-
if (!normalized.
|
|
1218
|
+
if (!normalized.type && typeof data.event === "string")
|
|
1219
|
+
normalized.type = data.event;
|
|
1220
|
+
if (!normalized.id && data.id !== void 0)
|
|
1221
|
+
normalized.id = data.id;
|
|
1222
|
+
if (!normalized.id && data.order_id !== void 0)
|
|
1223
|
+
normalized.id = data.order_id;
|
|
1224
|
+
if (!normalized.order_id && data.order_id !== void 0)
|
|
1225
|
+
normalized.order_id = data.order_id;
|
|
1226
|
+
if (!normalized.order_id && (payload == null ? void 0 : payload.order_id) !== void 0)
|
|
1227
|
+
normalized.order_id = payload.order_id;
|
|
1228
|
+
if (!normalized.body && (payload == null ? void 0 : payload.order_id) !== void 0)
|
|
1229
|
+
normalized.body = payload;
|
|
1230
|
+
if (!normalized.data && (payload == null ? void 0 : payload.order_id) !== void 0)
|
|
1231
|
+
normalized.data = payload;
|
|
1221
1232
|
return normalized;
|
|
1222
1233
|
}
|
|
1223
1234
|
normalizeOrderSyncPayload(payload) {
|
|
1224
|
-
if (!payload)
|
|
1235
|
+
if (!payload)
|
|
1236
|
+
return null;
|
|
1225
1237
|
const orderId = payload.order_id;
|
|
1226
|
-
if (orderId ===
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
order_id: orderId
|
|
1230
|
-
};
|
|
1238
|
+
if (orderId === void 0 || orderId === null)
|
|
1239
|
+
return null;
|
|
1240
|
+
return { ...payload, order_id: orderId };
|
|
1231
1241
|
}
|
|
1232
1242
|
uniqueOrderIds(ids) {
|
|
1233
|
-
const idMap = new Map();
|
|
1243
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
1234
1244
|
for (const id of ids) {
|
|
1235
1245
|
idMap.set(this.getIdKey(id), id);
|
|
1236
1246
|
}
|
|
@@ -1240,14 +1250,21 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1240
1250
|
return String(id);
|
|
1241
1251
|
}
|
|
1242
1252
|
isOrderLookupMatch(order, lookupKey) {
|
|
1243
|
-
if (!order || !lookupKey)
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1253
|
+
if (!order || !lookupKey)
|
|
1254
|
+
return false;
|
|
1255
|
+
const candidates = [
|
|
1256
|
+
order.order_id,
|
|
1257
|
+
order.external_sale_number,
|
|
1258
|
+
order.order_number,
|
|
1259
|
+
order.shop_order_number,
|
|
1260
|
+
order.shop_full_order_number
|
|
1261
|
+
];
|
|
1262
|
+
return candidates.some((value) => {
|
|
1263
|
+
if (value === void 0 || value === null || value === "")
|
|
1264
|
+
return false;
|
|
1247
1265
|
return this.getIdKey(value) === lookupKey;
|
|
1248
1266
|
});
|
|
1249
1267
|
}
|
|
1250
|
-
|
|
1251
1268
|
/**
|
|
1252
1269
|
* 解析订单 SQLite 主键,规则与宿主 OrderDataSource.getOrderStorageKey 一致。
|
|
1253
1270
|
*
|
|
@@ -1256,43 +1273,51 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1256
1273
|
* // => 'S-1001'
|
|
1257
1274
|
*/
|
|
1258
1275
|
getOrderStorageKey(order) {
|
|
1259
|
-
const externalSaleNumber = order
|
|
1260
|
-
if (externalSaleNumber !==
|
|
1276
|
+
const externalSaleNumber = order == null ? void 0 : order.external_sale_number;
|
|
1277
|
+
if (externalSaleNumber !== void 0 && externalSaleNumber !== null && externalSaleNumber !== "") {
|
|
1261
1278
|
return String(externalSaleNumber);
|
|
1262
1279
|
}
|
|
1263
|
-
const orderId = order
|
|
1264
|
-
if (orderId !==
|
|
1280
|
+
const orderId = order == null ? void 0 : order.order_id;
|
|
1281
|
+
if (orderId !== void 0 && orderId !== null && orderId !== "") {
|
|
1265
1282
|
return String(orderId);
|
|
1266
1283
|
}
|
|
1267
|
-
return
|
|
1284
|
+
return "";
|
|
1268
1285
|
}
|
|
1269
1286
|
getOrderIdentityMatchKeys(order) {
|
|
1270
|
-
return this.getOrderIdentityEntries(order).map(entry => `${entry.field}:${entry.key}`);
|
|
1287
|
+
return this.getOrderIdentityEntries(order).map((entry) => `${entry.field}:${entry.key}`);
|
|
1271
1288
|
}
|
|
1272
1289
|
doOrdersShareIdentity(left, right) {
|
|
1273
1290
|
const leftKeys = new Set(this.getOrderIdentityMatchKeys(left));
|
|
1274
|
-
if (leftKeys.size === 0)
|
|
1275
|
-
|
|
1291
|
+
if (leftKeys.size === 0)
|
|
1292
|
+
return false;
|
|
1293
|
+
return this.getOrderIdentityMatchKeys(right).some((key) => leftKeys.has(key));
|
|
1276
1294
|
}
|
|
1277
1295
|
findOrderIndexByIdentity(orders, target) {
|
|
1278
|
-
if (this.getOrderIdentityMatchKeys(target).length === 0)
|
|
1279
|
-
|
|
1296
|
+
if (this.getOrderIdentityMatchKeys(target).length === 0)
|
|
1297
|
+
return -1;
|
|
1298
|
+
return orders.findIndex((order) => this.doOrdersShareIdentity(order, target));
|
|
1280
1299
|
}
|
|
1281
1300
|
getOrderCompletenessScore(order) {
|
|
1282
1301
|
const record = order;
|
|
1283
1302
|
let score = this.isPendingSyncOrder(order) ? 0 : 100;
|
|
1284
|
-
if (!this.isBlankIdentityValue(order.order_id) && order.order_id !== record.external_sale_number)
|
|
1303
|
+
if (!this.isBlankIdentityValue(order.order_id) && order.order_id !== record.external_sale_number)
|
|
1304
|
+
score += 30;
|
|
1285
1305
|
score += this.getOrderIdentityMatchKeys(order).length * 5;
|
|
1286
|
-
if (Array.isArray(order.products))
|
|
1287
|
-
|
|
1288
|
-
if (Array.isArray(order.
|
|
1289
|
-
|
|
1306
|
+
if (Array.isArray(order.products))
|
|
1307
|
+
score += Math.min(order.products.length, 10);
|
|
1308
|
+
if (Array.isArray(order.bookings))
|
|
1309
|
+
score += Math.min(order.bookings.length, 10);
|
|
1310
|
+
if (Array.isArray(order.payments))
|
|
1311
|
+
score += Math.min(order.payments.length, 10);
|
|
1312
|
+
if (record.updated_at)
|
|
1313
|
+
score += 1;
|
|
1290
1314
|
return score;
|
|
1291
1315
|
}
|
|
1292
1316
|
pickPreferredOrder(left, right) {
|
|
1293
1317
|
const leftScore = this.getOrderCompletenessScore(left);
|
|
1294
1318
|
const rightScore = this.getOrderCompletenessScore(right);
|
|
1295
|
-
if (rightScore >= leftScore)
|
|
1319
|
+
if (rightScore >= leftScore)
|
|
1320
|
+
return right;
|
|
1296
1321
|
return left;
|
|
1297
1322
|
}
|
|
1298
1323
|
mergeOrderRecords(existing, incoming) {
|
|
@@ -1302,8 +1327,30 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1302
1327
|
...secondary,
|
|
1303
1328
|
...preferred
|
|
1304
1329
|
};
|
|
1305
|
-
const fieldsToPreserve = [
|
|
1306
|
-
|
|
1330
|
+
const fieldsToPreserve = [
|
|
1331
|
+
"order_id",
|
|
1332
|
+
"external_sale_number",
|
|
1333
|
+
"order_number",
|
|
1334
|
+
"shop_order_number",
|
|
1335
|
+
"shop_full_order_number"
|
|
1336
|
+
];
|
|
1337
|
+
const incomingPatchFields = [
|
|
1338
|
+
"payment_status",
|
|
1339
|
+
"status",
|
|
1340
|
+
"shipping_status",
|
|
1341
|
+
"updated_at",
|
|
1342
|
+
"shop_discount",
|
|
1343
|
+
"summary",
|
|
1344
|
+
"note",
|
|
1345
|
+
"customer_id",
|
|
1346
|
+
"customer_name",
|
|
1347
|
+
"customer",
|
|
1348
|
+
"holder",
|
|
1349
|
+
"contacts_info",
|
|
1350
|
+
"phone",
|
|
1351
|
+
"email",
|
|
1352
|
+
"relation_forms"
|
|
1353
|
+
];
|
|
1307
1354
|
const mergedRecord = merged;
|
|
1308
1355
|
const preferredRecord = preferred;
|
|
1309
1356
|
const secondaryRecord = secondary;
|
|
@@ -1320,21 +1367,26 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1320
1367
|
}
|
|
1321
1368
|
}
|
|
1322
1369
|
for (const field of incomingPatchFields) {
|
|
1323
|
-
if (!Object.prototype.hasOwnProperty.call(incomingRecord, field))
|
|
1324
|
-
|
|
1325
|
-
if (
|
|
1326
|
-
|
|
1370
|
+
if (!Object.prototype.hasOwnProperty.call(incomingRecord, field))
|
|
1371
|
+
continue;
|
|
1372
|
+
if (incomingRecord[field] === void 0 || incomingRecord[field] === null)
|
|
1373
|
+
continue;
|
|
1374
|
+
if (typeof incomingRecord[field] === "string" && incomingRecord[field] === "")
|
|
1375
|
+
continue;
|
|
1376
|
+
mergedRecord[field] = (0, import_lodash_es.cloneDeep)(incomingRecord[field]);
|
|
1327
1377
|
}
|
|
1328
|
-
|
|
1329
|
-
// 子项数组遵循完整快照语义:incoming 自有且为数组(包括 [])时权威替换;
|
|
1330
|
-
// 字段缺席或不是数组时视为稀疏 patch,继续保留 existing。
|
|
1331
1378
|
for (const field of ORDER_AUTHORITATIVE_COLLECTION_FIELDS) {
|
|
1332
1379
|
if (Array.isArray(incomingRecord[field])) {
|
|
1333
|
-
mergedRecord[field] = this.mergeAuthoritativeOrderCollection(
|
|
1380
|
+
mergedRecord[field] = this.mergeAuthoritativeOrderCollection(
|
|
1381
|
+
field,
|
|
1382
|
+
existingRecord[field],
|
|
1383
|
+
incomingRecord[field],
|
|
1384
|
+
childUidRemaps
|
|
1385
|
+
);
|
|
1334
1386
|
continue;
|
|
1335
1387
|
}
|
|
1336
1388
|
if (Object.prototype.hasOwnProperty.call(existingRecord, field)) {
|
|
1337
|
-
mergedRecord[field] = (0,
|
|
1389
|
+
mergedRecord[field] = (0, import_lodash_es.cloneDeep)(existingRecord[field]);
|
|
1338
1390
|
} else {
|
|
1339
1391
|
delete mergedRecord[field];
|
|
1340
1392
|
}
|
|
@@ -1342,10 +1394,13 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1342
1394
|
if (!this.isPendingSyncOrder(preferred) || !this.isPendingSyncOrder(secondary)) {
|
|
1343
1395
|
merged.need_sync = 0;
|
|
1344
1396
|
}
|
|
1345
|
-
return this.normalizeOrderCollectionsForIngress(
|
|
1397
|
+
return this.normalizeOrderCollectionsForIngress(
|
|
1398
|
+
(0, import_orderCollectionIdentity.applyOrderCollectionUidRemaps)(merged, childUidRemaps),
|
|
1399
|
+
"mergeOrderRecords"
|
|
1400
|
+
);
|
|
1346
1401
|
}
|
|
1347
1402
|
summarizeDuplicateOrders(orders) {
|
|
1348
|
-
const groups = new Map();
|
|
1403
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1349
1404
|
for (const order of orders) {
|
|
1350
1405
|
for (const key of this.getOrderIdentityMatchKeys(order)) {
|
|
1351
1406
|
const group = groups.get(key) || [];
|
|
@@ -1356,7 +1411,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1356
1411
|
return [...groups.entries()].filter(([, group]) => group.length > 1).slice(0, 20).map(([key, group]) => ({
|
|
1357
1412
|
key,
|
|
1358
1413
|
count: group.length,
|
|
1359
|
-
orders: group.map(order => ({
|
|
1414
|
+
orders: group.map((order) => ({
|
|
1360
1415
|
order_id: order.order_id ?? null,
|
|
1361
1416
|
external_sale_number: order.external_sale_number ?? null,
|
|
1362
1417
|
shop_order_number: order.shop_order_number ?? null,
|
|
@@ -1367,8 +1422,9 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1367
1422
|
}
|
|
1368
1423
|
logDuplicateOrders(source, orders) {
|
|
1369
1424
|
const duplicateGroups = this.summarizeDuplicateOrders(orders);
|
|
1370
|
-
if (duplicateGroups.length === 0)
|
|
1371
|
-
|
|
1425
|
+
if (duplicateGroups.length === 0)
|
|
1426
|
+
return;
|
|
1427
|
+
this.logWarning("检测到重复订单身份键", {
|
|
1372
1428
|
source,
|
|
1373
1429
|
duplicateGroupCount: duplicateGroups.length,
|
|
1374
1430
|
duplicateGroups
|
|
@@ -1378,7 +1434,10 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1378
1434
|
const list = [];
|
|
1379
1435
|
let removedCount = 0;
|
|
1380
1436
|
for (const order of orders) {
|
|
1381
|
-
const normalizedOrder = this.normalizeOrderCollectionsForIngress(
|
|
1437
|
+
const normalizedOrder = this.normalizeOrderCollectionsForIngress(
|
|
1438
|
+
order,
|
|
1439
|
+
`${source}.order`
|
|
1440
|
+
);
|
|
1382
1441
|
const matchIndex = this.findOrderIndexByIdentity(list, normalizedOrder);
|
|
1383
1442
|
if (matchIndex < 0) {
|
|
1384
1443
|
list.push(normalizedOrder);
|
|
@@ -1388,7 +1447,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1388
1447
|
removedCount += 1;
|
|
1389
1448
|
}
|
|
1390
1449
|
if (removedCount > 0) {
|
|
1391
|
-
this.logWarning(
|
|
1450
|
+
this.logWarning("订单列表重复项已压缩", {
|
|
1392
1451
|
source,
|
|
1393
1452
|
beforeCount: orders.length,
|
|
1394
1453
|
afterCount: list.length,
|
|
@@ -1397,113 +1456,115 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1397
1456
|
} else {
|
|
1398
1457
|
this.logDuplicateOrders(source, orders);
|
|
1399
1458
|
}
|
|
1400
|
-
return {
|
|
1401
|
-
list,
|
|
1402
|
-
removedCount
|
|
1403
|
-
};
|
|
1459
|
+
return { list, removedCount };
|
|
1404
1460
|
}
|
|
1405
|
-
|
|
1406
1461
|
/**
|
|
1407
1462
|
* 当前订单拉取窗口:
|
|
1408
1463
|
* - 优先使用 createdAtQuery.sales_time_between(已按营业日边界初始化)
|
|
1409
1464
|
* - 无法解析时退化为自然日窗口
|
|
1410
1465
|
*/
|
|
1411
1466
|
getCurrentPullWindow() {
|
|
1412
|
-
|
|
1413
|
-
const
|
|
1467
|
+
var _a, _b;
|
|
1468
|
+
const now = (0, import_dayjs.default)();
|
|
1469
|
+
const range = (_b = (_a = this.store) == null ? void 0 : _a.createdAtQuery) == null ? void 0 : _b.sales_time_between;
|
|
1414
1470
|
if (Array.isArray(range) && range.length >= 2) {
|
|
1415
|
-
const
|
|
1416
|
-
const endExclusiveAt = (0,
|
|
1417
|
-
if (
|
|
1418
|
-
return {
|
|
1419
|
-
startAt,
|
|
1420
|
-
endExclusiveAt
|
|
1421
|
-
};
|
|
1471
|
+
const startAt2 = (0, import_dayjs.default)(range[0]);
|
|
1472
|
+
const endExclusiveAt = (0, import_dayjs.default)(range[1]);
|
|
1473
|
+
if (startAt2.isValid() && endExclusiveAt.isValid() && endExclusiveAt.isAfter(startAt2)) {
|
|
1474
|
+
return { startAt: startAt2, endExclusiveAt };
|
|
1422
1475
|
}
|
|
1423
1476
|
}
|
|
1424
|
-
const startAt = now.startOf(
|
|
1425
|
-
return {
|
|
1426
|
-
startAt,
|
|
1427
|
-
endExclusiveAt: startAt.add(1, 'day')
|
|
1428
|
-
};
|
|
1477
|
+
const startAt = now.startOf("day");
|
|
1478
|
+
return { startAt, endExclusiveAt: startAt.add(1, "day") };
|
|
1429
1479
|
}
|
|
1430
1480
|
hasPulledOrdersToday() {
|
|
1431
1481
|
const lastFullFetchAt = this.getStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY);
|
|
1432
|
-
if (!lastFullFetchAt)
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
const {
|
|
1439
|
-
startAt,
|
|
1440
|
-
endExclusiveAt
|
|
1441
|
-
} = this.getCurrentPullWindow();
|
|
1482
|
+
if (!lastFullFetchAt)
|
|
1483
|
+
return false;
|
|
1484
|
+
const parsed = (0, import_dayjs.default)(lastFullFetchAt);
|
|
1485
|
+
if (!parsed.isValid())
|
|
1486
|
+
return false;
|
|
1487
|
+
const { startAt, endExclusiveAt } = this.getCurrentPullWindow();
|
|
1442
1488
|
return (parsed.isAfter(startAt) || parsed.isSame(startAt)) && parsed.isBefore(endExclusiveAt);
|
|
1443
1489
|
}
|
|
1444
1490
|
markOrderPulledAtNow() {
|
|
1445
|
-
this.setStorageItem(
|
|
1491
|
+
this.setStorageItem(
|
|
1492
|
+
ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY,
|
|
1493
|
+
(0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
|
|
1494
|
+
);
|
|
1446
1495
|
}
|
|
1447
1496
|
getStorageItem(key) {
|
|
1497
|
+
var _a;
|
|
1448
1498
|
try {
|
|
1449
|
-
if (this.storage
|
|
1450
|
-
|
|
1499
|
+
if ((_a = this.storage) == null ? void 0 : _a.getStorage)
|
|
1500
|
+
return this.storage.getStorage(key);
|
|
1501
|
+
if (typeof globalThis !== "undefined" && (globalThis == null ? void 0 : globalThis.localStorage)) {
|
|
1451
1502
|
return globalThis.localStorage.getItem(key);
|
|
1452
1503
|
}
|
|
1453
1504
|
} catch {
|
|
1454
|
-
// 忽略存储异常,避免影响主流程
|
|
1455
1505
|
}
|
|
1456
1506
|
return null;
|
|
1457
1507
|
}
|
|
1458
1508
|
setStorageItem(key, value) {
|
|
1509
|
+
var _a;
|
|
1459
1510
|
try {
|
|
1460
|
-
if (this.storage
|
|
1511
|
+
if ((_a = this.storage) == null ? void 0 : _a.setStorage) {
|
|
1461
1512
|
this.storage.setStorage(key, value);
|
|
1462
1513
|
return;
|
|
1463
1514
|
}
|
|
1464
|
-
if (typeof globalThis !==
|
|
1515
|
+
if (typeof globalThis !== "undefined" && (globalThis == null ? void 0 : globalThis.localStorage)) {
|
|
1465
1516
|
globalThis.localStorage.setItem(key, value);
|
|
1466
1517
|
}
|
|
1467
1518
|
} catch {
|
|
1468
|
-
// 忽略存储异常,避免影响主流程
|
|
1469
1519
|
}
|
|
1470
1520
|
}
|
|
1471
1521
|
async loadOrdersFromSQLite() {
|
|
1472
|
-
if (!this.dbManager)
|
|
1522
|
+
if (!this.dbManager)
|
|
1523
|
+
return [];
|
|
1473
1524
|
try {
|
|
1474
1525
|
const orders = await this.dbManager.getAll(INDEXDB_STORE_NAME);
|
|
1475
|
-
return (orders || []).map(
|
|
1526
|
+
return (orders || []).map(
|
|
1527
|
+
(order) => this.normalizeOrderCollectionsForIngress(order, "loadOrdersFromSQLite")
|
|
1528
|
+
);
|
|
1476
1529
|
} catch {
|
|
1477
1530
|
return [];
|
|
1478
1531
|
}
|
|
1479
1532
|
}
|
|
1480
1533
|
isPendingSyncOrder(order) {
|
|
1481
|
-
return Number(order
|
|
1534
|
+
return Number(order == null ? void 0 : order.need_sync) === 1;
|
|
1482
1535
|
}
|
|
1483
1536
|
normalizeRemoteSyncedOrder(order) {
|
|
1484
|
-
const normalizedOrder = this.normalizeOrderCollectionsForIngress(
|
|
1485
|
-
|
|
1537
|
+
const normalizedOrder = this.normalizeOrderCollectionsForIngress(
|
|
1538
|
+
order,
|
|
1539
|
+
"normalizeRemoteSyncedOrder"
|
|
1540
|
+
);
|
|
1541
|
+
if (this.isPendingSyncOrder(normalizedOrder))
|
|
1542
|
+
return normalizedOrder;
|
|
1486
1543
|
return {
|
|
1487
1544
|
...normalizedOrder,
|
|
1488
1545
|
need_sync: 0
|
|
1489
1546
|
};
|
|
1490
1547
|
}
|
|
1491
1548
|
mergeRemoteSnapshotWithPendingOrders(remoteOrders, existingOrders) {
|
|
1492
|
-
const merged = remoteOrders.map(order => this.normalizeRemoteSyncedOrder(order));
|
|
1549
|
+
const merged = remoteOrders.map((order) => this.normalizeRemoteSyncedOrder(order));
|
|
1493
1550
|
for (const rawOrder of existingOrders) {
|
|
1494
|
-
const order = this.normalizeOrderCollectionsForIngress(
|
|
1495
|
-
|
|
1551
|
+
const order = this.normalizeOrderCollectionsForIngress(
|
|
1552
|
+
rawOrder,
|
|
1553
|
+
"mergeRemoteSnapshotWithPendingOrders.existingSQLite"
|
|
1554
|
+
);
|
|
1555
|
+
if (!this.isPendingSyncOrder(order))
|
|
1556
|
+
continue;
|
|
1496
1557
|
const matchIndex = this.findOrderIndexByIdentity(merged, order);
|
|
1497
1558
|
if (matchIndex >= 0) {
|
|
1498
1559
|
merged[matchIndex] = this.mergeOrderRecords(order, merged[matchIndex]);
|
|
1499
1560
|
continue;
|
|
1500
1561
|
}
|
|
1501
|
-
if (!this.getOrderStorageKey(order))
|
|
1562
|
+
if (!this.getOrderStorageKey(order))
|
|
1563
|
+
continue;
|
|
1502
1564
|
merged.push(order);
|
|
1503
1565
|
}
|
|
1504
|
-
return this.compactOrderListByIdentity(merged,
|
|
1566
|
+
return this.compactOrderListByIdentity(merged, "mergeRemoteSnapshotWithPendingOrders").list;
|
|
1505
1567
|
}
|
|
1506
|
-
|
|
1507
1568
|
/**
|
|
1508
1569
|
* 串行执行订单 SQLite 写入任务,避免快照替换与增量 upsert 并发交错。
|
|
1509
1570
|
*
|
|
@@ -1514,10 +1575,9 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1514
1575
|
*/
|
|
1515
1576
|
async runInOrderSQLiteSaveQueue(task) {
|
|
1516
1577
|
const queuedTask = this.orderSQLiteSaveQueue.then(task, task);
|
|
1517
|
-
this.orderSQLiteSaveQueue = queuedTask.then(() =>
|
|
1578
|
+
this.orderSQLiteSaveQueue = queuedTask.then(() => void 0, () => void 0);
|
|
1518
1579
|
return queuedTask;
|
|
1519
1580
|
}
|
|
1520
|
-
|
|
1521
1581
|
/**
|
|
1522
1582
|
* 批量增量 upsert 订单到 SQLite,不清空表;用于 pubsub / HTTP 增量合并。
|
|
1523
1583
|
*
|
|
@@ -1528,14 +1588,15 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1528
1588
|
if (!this.dbManager || orders.length === 0) {
|
|
1529
1589
|
return;
|
|
1530
1590
|
}
|
|
1531
|
-
const ordersSnapshot = (0,
|
|
1591
|
+
const ordersSnapshot = (0, import_lodash_es.cloneDeep)(orders).map((order) => this.normalizeOrderCollectionsForIngress(order, `${source}.sqliteIngress`)).filter((order) => this.getOrderStorageKey(order));
|
|
1532
1592
|
if (ordersSnapshot.length === 0) {
|
|
1533
1593
|
return;
|
|
1534
1594
|
}
|
|
1535
|
-
const {
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1595
|
+
const { toWrite, skipped } = this.filterRedundantPatchOrders(
|
|
1596
|
+
source,
|
|
1597
|
+
ordersSnapshot,
|
|
1598
|
+
mergeActions
|
|
1599
|
+
);
|
|
1539
1600
|
if (toWrite.length === 0) {
|
|
1540
1601
|
return;
|
|
1541
1602
|
}
|
|
@@ -1545,26 +1606,26 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1545
1606
|
}
|
|
1546
1607
|
try {
|
|
1547
1608
|
await this.runInOrderSQLiteSaveQueue(async () => {
|
|
1548
|
-
let writeMethod =
|
|
1549
|
-
this.logInfo(
|
|
1609
|
+
let writeMethod = "none";
|
|
1610
|
+
this.logInfo("patchOrdersInSQLite-开始", {
|
|
1550
1611
|
source,
|
|
1551
1612
|
count: compactedToWrite.length,
|
|
1552
1613
|
dedupedCount: skipped.length
|
|
1553
1614
|
});
|
|
1554
|
-
if (typeof this.dbManager.bulkUpdate ===
|
|
1555
|
-
writeMethod =
|
|
1615
|
+
if (typeof this.dbManager.bulkUpdate === "function") {
|
|
1616
|
+
writeMethod = "bulkUpdate";
|
|
1556
1617
|
await this.dbManager.bulkUpdate(INDEXDB_STORE_NAME, compactedToWrite);
|
|
1557
|
-
} else if (typeof this.dbManager.bulkAdd ===
|
|
1558
|
-
writeMethod =
|
|
1618
|
+
} else if (typeof this.dbManager.bulkAdd === "function") {
|
|
1619
|
+
writeMethod = "bulkAdd";
|
|
1559
1620
|
await this.dbManager.bulkAdd(INDEXDB_STORE_NAME, compactedToWrite);
|
|
1560
|
-
} else if (typeof this.dbManager.update ===
|
|
1561
|
-
writeMethod =
|
|
1621
|
+
} else if (typeof this.dbManager.update === "function") {
|
|
1622
|
+
writeMethod = "update";
|
|
1562
1623
|
for (const order of compactedToWrite) {
|
|
1563
1624
|
await this.dbManager.update(INDEXDB_STORE_NAME, order);
|
|
1564
1625
|
}
|
|
1565
1626
|
}
|
|
1566
1627
|
this.recordRecentSqliteWrite(source, compactedToWrite);
|
|
1567
|
-
this.logInfo(
|
|
1628
|
+
this.logInfo("patchOrdersInSQLite-完成", {
|
|
1568
1629
|
source,
|
|
1569
1630
|
count: compactedToWrite.length,
|
|
1570
1631
|
writeMethod,
|
|
@@ -1572,13 +1633,12 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1572
1633
|
});
|
|
1573
1634
|
});
|
|
1574
1635
|
} catch (error) {
|
|
1575
|
-
this.logError(
|
|
1636
|
+
this.logError("增量保存订单到 SQLite 失败", {
|
|
1576
1637
|
error: error instanceof Error ? error.message : String(error),
|
|
1577
1638
|
orderCount: ordersSnapshot.length
|
|
1578
1639
|
});
|
|
1579
1640
|
}
|
|
1580
1641
|
}
|
|
1581
|
-
|
|
1582
1642
|
/**
|
|
1583
1643
|
* 单条 upsert 订单到 SQLite;用于 overwriteExistingOrder 等单条覆盖场景。
|
|
1584
1644
|
*
|
|
@@ -1589,40 +1649,42 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1589
1649
|
if (!this.dbManager || !this.getOrderStorageKey(order)) {
|
|
1590
1650
|
return;
|
|
1591
1651
|
}
|
|
1592
|
-
const orderSnapshot = this.normalizeOrderCollectionsForIngress(
|
|
1652
|
+
const orderSnapshot = this.normalizeOrderCollectionsForIngress(
|
|
1653
|
+
(0, import_lodash_es.cloneDeep)(order),
|
|
1654
|
+
`${source}.sqliteIngress`
|
|
1655
|
+
);
|
|
1593
1656
|
try {
|
|
1594
1657
|
await this.runInOrderSQLiteSaveQueue(async () => {
|
|
1595
|
-
let writeMethod =
|
|
1596
|
-
this.logInfo(
|
|
1658
|
+
let writeMethod = "none";
|
|
1659
|
+
this.logInfo("updateOrderInSQLite-开始", {
|
|
1597
1660
|
source,
|
|
1598
1661
|
orderId: orderSnapshot.order_id ?? null,
|
|
1599
1662
|
storageKey: this.getOrderStorageKey(orderSnapshot)
|
|
1600
1663
|
});
|
|
1601
|
-
if (typeof this.dbManager.update ===
|
|
1602
|
-
writeMethod =
|
|
1664
|
+
if (typeof this.dbManager.update === "function") {
|
|
1665
|
+
writeMethod = "update";
|
|
1603
1666
|
await this.dbManager.update(INDEXDB_STORE_NAME, orderSnapshot);
|
|
1604
|
-
} else if (typeof this.dbManager.bulkUpdate ===
|
|
1605
|
-
writeMethod =
|
|
1667
|
+
} else if (typeof this.dbManager.bulkUpdate === "function") {
|
|
1668
|
+
writeMethod = "bulkUpdate";
|
|
1606
1669
|
await this.dbManager.bulkUpdate(INDEXDB_STORE_NAME, [orderSnapshot]);
|
|
1607
|
-
} else if (typeof this.dbManager.bulkAdd ===
|
|
1608
|
-
writeMethod =
|
|
1670
|
+
} else if (typeof this.dbManager.bulkAdd === "function") {
|
|
1671
|
+
writeMethod = "bulkAdd";
|
|
1609
1672
|
await this.dbManager.bulkAdd(INDEXDB_STORE_NAME, [orderSnapshot]);
|
|
1610
1673
|
}
|
|
1611
1674
|
this.recordRecentSqliteWrite(source, [orderSnapshot]);
|
|
1612
|
-
this.logInfo(
|
|
1675
|
+
this.logInfo("updateOrderInSQLite-完成", {
|
|
1613
1676
|
source,
|
|
1614
1677
|
orderId: orderSnapshot.order_id ?? null,
|
|
1615
1678
|
writeMethod
|
|
1616
1679
|
});
|
|
1617
1680
|
});
|
|
1618
1681
|
} catch (error) {
|
|
1619
|
-
this.logError(
|
|
1682
|
+
this.logError("单条保存订单到 SQLite 失败", {
|
|
1620
1683
|
error: error instanceof Error ? error.message : String(error),
|
|
1621
1684
|
orderId: orderSnapshot.order_id ?? null
|
|
1622
1685
|
});
|
|
1623
1686
|
}
|
|
1624
1687
|
}
|
|
1625
|
-
|
|
1626
1688
|
/**
|
|
1627
1689
|
* 全量快照替换 orders 表(clear + bulkAdd),用于 SSE 全量拉取与营业日窗口裁剪。
|
|
1628
1690
|
*
|
|
@@ -1631,23 +1693,34 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1631
1693
|
*/
|
|
1632
1694
|
async replaceOrdersSnapshotInSQLite(orderList, source) {
|
|
1633
1695
|
if (!this.dbManager) {
|
|
1634
|
-
return this.compactOrderListByIdentity(
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1696
|
+
return this.compactOrderListByIdentity(
|
|
1697
|
+
orderList.map((order) => this.normalizeRemoteSyncedOrder(order)),
|
|
1698
|
+
`${source}.snapshotNoDb`
|
|
1699
|
+
).list;
|
|
1700
|
+
}
|
|
1701
|
+
const remoteSnapshot = (0, import_lodash_es.cloneDeep)(orderList).map(
|
|
1702
|
+
(order) => this.normalizeOrderCollectionsForIngress(order, `${source}.remoteIngress`)
|
|
1703
|
+
);
|
|
1704
|
+
let mergedSnapshot = this.compactOrderListByIdentity(
|
|
1705
|
+
remoteSnapshot.map((order) => this.normalizeRemoteSyncedOrder(order)),
|
|
1706
|
+
`${source}.remoteSnapshot`
|
|
1707
|
+
).list;
|
|
1638
1708
|
try {
|
|
1639
1709
|
await this.runInOrderSQLiteSaveQueue(async () => {
|
|
1640
|
-
const existingOrders = typeof this.dbManager.getAll ===
|
|
1641
|
-
const orderListSnapshot = this.mergeRemoteSnapshotWithPendingOrders(
|
|
1710
|
+
const existingOrders = typeof this.dbManager.getAll === "function" ? await this.dbManager.getAll(INDEXDB_STORE_NAME) : [];
|
|
1711
|
+
const orderListSnapshot = this.mergeRemoteSnapshotWithPendingOrders(
|
|
1712
|
+
remoteSnapshot,
|
|
1713
|
+
existingOrders || []
|
|
1714
|
+
);
|
|
1642
1715
|
mergedSnapshot = this.compactOrderListByIdentity(orderListSnapshot, `${source}.sqliteSnapshot`).list;
|
|
1643
|
-
this.logInfo(
|
|
1716
|
+
this.logInfo("replaceOrdersSnapshotInSQLite-开始", {
|
|
1644
1717
|
source,
|
|
1645
1718
|
count: mergedSnapshot.length,
|
|
1646
1719
|
remoteCount: remoteSnapshot.length,
|
|
1647
1720
|
preservedPendingCount: mergedSnapshot.length - remoteSnapshot.length
|
|
1648
1721
|
});
|
|
1649
1722
|
await this.dbManager.clear(INDEXDB_STORE_NAME);
|
|
1650
|
-
this.logInfo(
|
|
1723
|
+
this.logInfo("replaceOrdersSnapshotInSQLite-clear完成", {
|
|
1651
1724
|
count: mergedSnapshot.length
|
|
1652
1725
|
});
|
|
1653
1726
|
if (mergedSnapshot.length === 0) {
|
|
@@ -1655,20 +1728,19 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1655
1728
|
}
|
|
1656
1729
|
await this.dbManager.bulkAdd(INDEXDB_STORE_NAME, mergedSnapshot);
|
|
1657
1730
|
this.recordRecentSqliteWrite(source, mergedSnapshot);
|
|
1658
|
-
this.logInfo(
|
|
1731
|
+
this.logInfo("replaceOrdersSnapshotInSQLite-bulkAdd完成", {
|
|
1659
1732
|
source,
|
|
1660
1733
|
count: mergedSnapshot.length
|
|
1661
1734
|
});
|
|
1662
1735
|
});
|
|
1663
1736
|
} catch (error) {
|
|
1664
|
-
this.logError(
|
|
1737
|
+
this.logError("全量保存订单到 SQLite 失败", {
|
|
1665
1738
|
error: error instanceof Error ? error.message : String(error),
|
|
1666
1739
|
orderList: remoteSnapshot.length
|
|
1667
1740
|
});
|
|
1668
1741
|
}
|
|
1669
1742
|
return mergedSnapshot;
|
|
1670
1743
|
}
|
|
1671
|
-
|
|
1672
1744
|
/**
|
|
1673
1745
|
* 清空订单模块的内存数据和本地 SQLite 订单表。
|
|
1674
1746
|
*
|
|
@@ -1677,14 +1749,17 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1677
1749
|
*/
|
|
1678
1750
|
async clear() {
|
|
1679
1751
|
this.store.list = [];
|
|
1680
|
-
this.store.map = new Map();
|
|
1752
|
+
this.store.map = /* @__PURE__ */ new Map();
|
|
1681
1753
|
if (this.dbManager) {
|
|
1682
1754
|
await this.runInOrderSQLiteSaveQueue(async () => {
|
|
1683
1755
|
await this.dbManager.clear(INDEXDB_STORE_NAME);
|
|
1684
1756
|
});
|
|
1685
1757
|
}
|
|
1686
|
-
this.setStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY,
|
|
1687
|
-
this.emitOrdersChanged([],
|
|
1758
|
+
this.setStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY, "");
|
|
1759
|
+
this.emitOrdersChanged([], "clear");
|
|
1688
1760
|
}
|
|
1689
|
-
}
|
|
1690
|
-
|
|
1761
|
+
};
|
|
1762
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1763
|
+
0 && (module.exports = {
|
|
1764
|
+
OrderModule
|
|
1765
|
+
});
|