@pisell/pisellos 2.2.244 → 2.2.246

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. package/dist/model/strategy/adapter/promotion/evaluator.js +3 -2
  2. package/dist/model/strategy/adapter/walletPass/utils.js +7 -4
  3. package/dist/modules/BookingContext/index.d.ts +48 -0
  4. package/dist/modules/BookingContext/index.js +566 -0
  5. package/dist/modules/BookingContext/types.d.ts +102 -0
  6. package/dist/modules/BookingContext/types.js +51 -0
  7. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
  8. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +284 -0
  9. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
  10. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +148 -0
  11. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +76 -0
  12. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +218 -0
  13. package/dist/modules/BookingContext/utils/flexible.d.ts +28 -0
  14. package/dist/modules/BookingContext/utils/flexible.js +56 -0
  15. package/dist/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
  16. package/dist/modules/BookingContext/utils/formatResourceList.js +38 -0
  17. package/dist/modules/BookingContext/utils/index.d.ts +11 -0
  18. package/dist/modules/BookingContext/utils/index.js +11 -0
  19. package/dist/modules/BookingContext/utils/noResource.d.ts +13 -0
  20. package/dist/modules/BookingContext/utils/noResource.js +77 -0
  21. package/dist/modules/BookingContext/utils/orderLineDisplay.d.ts +1 -0
  22. package/dist/modules/BookingContext/utils/orderLineDisplay.js +36 -0
  23. package/dist/modules/BookingContext/utils/productExtend.d.ts +72 -0
  24. package/dist/modules/BookingContext/utils/productExtend.js +339 -0
  25. package/dist/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
  26. package/dist/modules/BookingContext/utils/resourceErrors.js +74 -0
  27. package/dist/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
  28. package/dist/modules/BookingContext/utils/resourceSelection.js +24 -0
  29. package/dist/modules/BookingContext/utils/resources.d.ts +80 -0
  30. package/dist/modules/BookingContext/utils/resources.js +486 -0
  31. package/dist/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
  32. package/dist/modules/BookingContext/utils/serviceTimes.js +151 -0
  33. package/dist/modules/BookingContext/utils/timeSlices.d.ts +42 -0
  34. package/dist/modules/BookingContext/utils/timeSlices.js +100 -0
  35. package/dist/modules/Cart/utils/cartProduct.js +24 -3
  36. package/dist/modules/Cart/utils/changePrice.js +11 -11
  37. package/dist/modules/Customer/index.d.ts +20 -0
  38. package/dist/modules/Customer/index.js +172 -83
  39. package/dist/modules/Customer/types.d.ts +2 -0
  40. package/dist/modules/Discount/index.d.ts +1 -1
  41. package/dist/modules/Discount/index.js +13 -6
  42. package/dist/modules/Discount/types.d.ts +1 -0
  43. package/dist/modules/OpenData/index.d.ts +8 -0
  44. package/dist/modules/OpenData/index.js +37 -17
  45. package/dist/modules/Order/index.d.ts +277 -18
  46. package/dist/modules/Order/index.js +3581 -779
  47. package/dist/modules/Order/types.d.ts +286 -31
  48. package/dist/modules/Order/types.js +38 -0
  49. package/dist/modules/Order/utils/manualProductDiscount.d.ts +106 -0
  50. package/dist/modules/Order/utils/manualProductDiscount.js +210 -0
  51. package/dist/modules/Order/utils.d.ts +147 -5
  52. package/dist/modules/Order/utils.js +750 -104
  53. package/dist/modules/Payment/index.d.ts +10 -13
  54. package/dist/modules/Payment/index.js +467 -837
  55. package/dist/modules/Payment/types.d.ts +2 -0
  56. package/dist/modules/Payment/utils.js +2 -1
  57. package/dist/modules/Payment/walletpass.js +41 -25
  58. package/dist/modules/ProductList/index.d.ts +16 -12
  59. package/dist/modules/ProductList/index.js +133 -59
  60. package/dist/modules/ProductList/types.d.ts +14 -0
  61. package/dist/modules/Quotation/index.d.ts +0 -1
  62. package/dist/modules/Quotation/index.js +25 -22
  63. package/dist/modules/Rules/index.d.ts +4 -0
  64. package/dist/modules/Rules/index.js +97 -70
  65. package/dist/modules/Rules/types.d.ts +1 -0
  66. package/dist/modules/SalesSummary/index.d.ts +8 -25
  67. package/dist/modules/SalesSummary/index.js +86 -35
  68. package/dist/modules/SalesSummary/types.d.ts +4 -1
  69. package/dist/modules/SalesSummary/utils.d.ts +2 -25
  70. package/dist/modules/SalesSummary/utils.js +794 -162
  71. package/dist/modules/Schedule/index.d.ts +7 -0
  72. package/dist/modules/Schedule/index.js +24 -2
  73. package/dist/modules/Summary/index.js +4 -3
  74. package/dist/modules/SurchargeList/index.d.ts +16 -0
  75. package/dist/modules/SurchargeList/index.js +162 -0
  76. package/dist/modules/SurchargeList/types.d.ts +11 -0
  77. package/dist/modules/SurchargeList/types.js +1 -0
  78. package/dist/modules/index.d.ts +2 -0
  79. package/dist/modules/index.js +3 -1
  80. package/dist/plugins/request.d.ts +1 -0
  81. package/dist/server/index.d.ts +204 -1
  82. package/dist/server/index.js +3654 -922
  83. package/dist/server/modules/index.d.ts +2 -0
  84. package/dist/server/modules/index.js +2 -0
  85. package/dist/server/modules/order/index.d.ts +120 -3
  86. package/dist/server/modules/order/index.js +1762 -448
  87. package/dist/server/modules/order/types.d.ts +32 -3
  88. package/dist/server/modules/order/types.js +8 -0
  89. package/dist/server/modules/order/utils/filterBookings.js +26 -3
  90. package/dist/server/modules/order/utils/filterOrders.js +23 -8
  91. package/dist/server/modules/payment/index.d.ts +28 -0
  92. package/dist/server/modules/payment/index.js +305 -0
  93. package/dist/server/modules/payment/types.d.ts +9 -0
  94. package/dist/server/modules/payment/types.js +1 -0
  95. package/dist/server/modules/products/index.d.ts +34 -7
  96. package/dist/server/modules/products/index.js +631 -317
  97. package/dist/server/modules/resource/index.d.ts +2 -0
  98. package/dist/server/modules/resource/index.js +29 -3
  99. package/dist/server/modules/schedule/index.d.ts +4 -4
  100. package/dist/server/modules/schedule/index.js +111 -88
  101. package/dist/server/test.json +713 -0
  102. package/dist/server/utils/small-ticket.d.ts +71 -0
  103. package/dist/server/utils/small-ticket.js +840 -0
  104. package/dist/solution/BaseSales/index.d.ts +133 -10
  105. package/dist/solution/BaseSales/index.js +1950 -447
  106. package/dist/solution/BaseSales/types.d.ts +82 -6
  107. package/dist/solution/BaseSales/types.js +5 -4
  108. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +287 -0
  109. package/dist/solution/BaseSales/utils/cartPromotion.js +1438 -0
  110. package/dist/solution/BaseSales/utils/quotationPrice.d.ts +7 -0
  111. package/dist/solution/BaseSales/utils/quotationPrice.js +237 -0
  112. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
  113. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +105 -24
  114. package/dist/solution/BaseSales/utils.d.ts +1 -1
  115. package/dist/solution/BaseSales/utils.js +62 -21
  116. package/dist/solution/BookingByStep/index.d.ts +1 -1
  117. package/dist/solution/BookingTicket/index.d.ts +271 -11
  118. package/dist/solution/BookingTicket/index.js +1777 -242
  119. package/dist/solution/BookingTicket/types.d.ts +118 -1
  120. package/dist/solution/BookingTicket/types.js +41 -2
  121. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +117 -0
  122. package/dist/solution/BookingTicket/utils/addProductDecision.js +346 -0
  123. package/dist/solution/BookingTicket/utils/addTimeAvailability.d.ts +35 -0
  124. package/dist/solution/BookingTicket/utils/addTimeAvailability.js +95 -0
  125. package/dist/solution/BookingTicket/utils/bookingStatus.d.ts +40 -0
  126. package/dist/solution/BookingTicket/utils/bookingStatus.js +70 -0
  127. package/dist/solution/BookingTicket/utils/cartView.d.ts +9 -1
  128. package/dist/solution/BookingTicket/utils/cartView.js +94 -7
  129. package/dist/solution/BookingTicket/utils/exampleData.d.ts +123 -0
  130. package/dist/solution/BookingTicket/utils/exampleData.js +183 -0
  131. package/dist/solution/BookingTicket/utils/resolveBestAddTimePlan.d.ts +185 -0
  132. package/dist/solution/BookingTicket/utils/resolveBestAddTimePlan.js +438 -0
  133. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +36 -0
  134. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +400 -0
  135. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +32 -0
  136. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.js +56 -0
  137. package/dist/solution/BookingTicket/utils/scan/index.d.ts +5 -0
  138. package/dist/solution/BookingTicket/utils/scan/index.js +20 -8
  139. package/dist/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
  140. package/dist/solution/BookingTicket/utils/scan/scanProductValues.js +150 -0
  141. package/dist/solution/BookingTicket/utils/sessionCatalogStale.d.ts +23 -0
  142. package/dist/solution/BookingTicket/utils/sessionCatalogStale.js +78 -0
  143. package/dist/solution/Checkout/index.d.ts +1 -0
  144. package/dist/solution/Checkout/index.js +10 -9
  145. package/dist/solution/RegisterAndLogin/config.js +2 -10
  146. package/dist/solution/ScanOrder/index.d.ts +9 -3
  147. package/dist/solution/ScanOrder/index.js +241 -134
  148. package/dist/solution/ScanOrder/types.d.ts +9 -5
  149. package/dist/solution/ScanOrder/types.js +2 -3
  150. package/dist/solution/ScanOrder/utils.d.ts +1 -1
  151. package/dist/solution/ScanOrder/utils.js +84 -22
  152. package/dist/solution/VenueBooking/index.d.ts +5 -2
  153. package/dist/solution/VenueBooking/index.js +110 -59
  154. package/dist/solution/VenueBooking/sales-section-4-annotated.json +0 -2
  155. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +4 -0
  156. package/dist/solution/VenueBooking/utils/slotMerge.js +10 -0
  157. package/dist/types/index.d.ts +10 -0
  158. package/lib/model/strategy/adapter/promotion/evaluator.js +2 -1
  159. package/lib/model/strategy/adapter/promotion/index.js +49 -0
  160. package/lib/model/strategy/adapter/walletPass/utils.js +3 -2
  161. package/lib/modules/BookingContext/index.d.ts +48 -0
  162. package/lib/modules/BookingContext/index.js +368 -0
  163. package/lib/modules/BookingContext/types.d.ts +102 -0
  164. package/lib/modules/BookingContext/types.js +34 -0
  165. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
  166. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +276 -0
  167. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
  168. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +154 -0
  169. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +76 -0
  170. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +201 -0
  171. package/lib/modules/BookingContext/utils/flexible.d.ts +28 -0
  172. package/lib/modules/BookingContext/utils/flexible.js +80 -0
  173. package/lib/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
  174. package/lib/modules/BookingContext/utils/formatResourceList.js +50 -0
  175. package/lib/modules/BookingContext/utils/index.d.ts +11 -0
  176. package/lib/modules/BookingContext/utils/index.js +43 -0
  177. package/lib/modules/BookingContext/utils/noResource.d.ts +13 -0
  178. package/lib/modules/BookingContext/utils/noResource.js +90 -0
  179. package/lib/modules/BookingContext/utils/orderLineDisplay.d.ts +1 -0
  180. package/lib/modules/BookingContext/utils/orderLineDisplay.js +56 -0
  181. package/lib/modules/BookingContext/utils/productExtend.d.ts +72 -0
  182. package/lib/modules/BookingContext/utils/productExtend.js +283 -0
  183. package/lib/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
  184. package/lib/modules/BookingContext/utils/resourceErrors.js +80 -0
  185. package/lib/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
  186. package/lib/modules/BookingContext/utils/resourceSelection.js +46 -0
  187. package/lib/modules/BookingContext/utils/resources.d.ts +80 -0
  188. package/lib/modules/BookingContext/utils/resources.js +377 -0
  189. package/lib/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
  190. package/lib/modules/BookingContext/utils/serviceTimes.js +162 -0
  191. package/lib/modules/BookingContext/utils/timeSlices.d.ts +42 -0
  192. package/lib/modules/BookingContext/utils/timeSlices.js +124 -0
  193. package/lib/modules/Cart/utils/cartProduct.js +20 -3
  194. package/lib/modules/Cart/utils/changePrice.js +12 -20
  195. package/lib/modules/Customer/index.d.ts +20 -0
  196. package/lib/modules/Customer/index.js +64 -11
  197. package/lib/modules/Customer/types.d.ts +2 -0
  198. package/lib/modules/Discount/index.d.ts +1 -1
  199. package/lib/modules/Discount/index.js +9 -1
  200. package/lib/modules/Discount/types.d.ts +1 -0
  201. package/lib/modules/OpenData/index.d.ts +8 -0
  202. package/lib/modules/OpenData/index.js +19 -5
  203. package/lib/modules/Order/index.d.ts +277 -18
  204. package/lib/modules/Order/index.js +2317 -337
  205. package/lib/modules/Order/types.d.ts +286 -31
  206. package/lib/modules/Order/types.js +1 -0
  207. package/lib/modules/Order/utils/manualProductDiscount.d.ts +106 -0
  208. package/lib/modules/Order/utils/manualProductDiscount.js +206 -0
  209. package/lib/modules/Order/utils.d.ts +147 -5
  210. package/lib/modules/Order/utils.js +615 -46
  211. package/lib/modules/Payment/index.d.ts +10 -13
  212. package/lib/modules/Payment/index.js +18 -150
  213. package/lib/modules/Payment/types.d.ts +2 -0
  214. package/lib/modules/Payment/utils.js +2 -1
  215. package/lib/modules/Payment/walletpass.js +16 -3
  216. package/lib/modules/ProductList/index.d.ts +16 -12
  217. package/lib/modules/ProductList/index.js +41 -4
  218. package/lib/modules/ProductList/types.d.ts +14 -0
  219. package/lib/modules/Quotation/index.d.ts +0 -1
  220. package/lib/modules/Quotation/index.js +19 -16
  221. package/lib/modules/Rules/index.d.ts +4 -0
  222. package/lib/modules/Rules/index.js +137 -120
  223. package/lib/modules/Rules/types.d.ts +1 -0
  224. package/lib/modules/SalesSummary/index.d.ts +8 -25
  225. package/lib/modules/SalesSummary/index.js +30 -4
  226. package/lib/modules/SalesSummary/types.d.ts +4 -1
  227. package/lib/modules/SalesSummary/utils.d.ts +2 -25
  228. package/lib/modules/SalesSummary/utils.js +645 -91
  229. package/lib/modules/Schedule/index.d.ts +7 -0
  230. package/lib/modules/Schedule/index.js +17 -1
  231. package/lib/modules/Summary/index.js +5 -4
  232. package/lib/modules/SurchargeList/index.d.ts +16 -0
  233. package/lib/modules/SurchargeList/index.js +89 -0
  234. package/lib/modules/SurchargeList/types.d.ts +11 -0
  235. package/lib/modules/SurchargeList/types.js +17 -0
  236. package/lib/modules/index.d.ts +2 -0
  237. package/lib/modules/index.js +5 -1
  238. package/lib/plugins/request.d.ts +1 -0
  239. package/lib/server/index.d.ts +204 -1
  240. package/lib/server/index.js +1891 -59
  241. package/lib/server/modules/index.d.ts +2 -0
  242. package/lib/server/modules/index.js +3 -0
  243. package/lib/server/modules/order/index.d.ts +120 -3
  244. package/lib/server/modules/order/index.js +887 -94
  245. package/lib/server/modules/order/types.d.ts +32 -3
  246. package/lib/server/modules/order/utils/filterBookings.js +24 -5
  247. package/lib/server/modules/order/utils/filterOrders.js +15 -6
  248. package/lib/server/modules/payment/index.d.ts +28 -0
  249. package/lib/server/modules/payment/index.js +192 -0
  250. package/lib/server/modules/payment/types.d.ts +9 -0
  251. package/lib/server/modules/payment/types.js +17 -0
  252. package/lib/server/modules/products/index.d.ts +34 -7
  253. package/lib/server/modules/products/index.js +189 -54
  254. package/lib/server/modules/resource/index.d.ts +2 -0
  255. package/lib/server/modules/resource/index.js +27 -3
  256. package/lib/server/modules/schedule/index.d.ts +4 -4
  257. package/lib/server/modules/schedule/index.js +47 -40
  258. package/lib/server/test.json +713 -0
  259. package/lib/server/utils/small-ticket.d.ts +71 -0
  260. package/lib/server/utils/small-ticket.js +800 -0
  261. package/lib/solution/BaseSales/index.d.ts +133 -10
  262. package/lib/solution/BaseSales/index.js +1111 -63
  263. package/lib/solution/BaseSales/types.d.ts +82 -6
  264. package/lib/solution/BaseSales/types.js +3 -1
  265. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +287 -0
  266. package/lib/solution/BaseSales/utils/cartPromotion.js +992 -0
  267. package/lib/solution/BaseSales/utils/quotationPrice.d.ts +7 -0
  268. package/lib/solution/BaseSales/utils/quotationPrice.js +277 -0
  269. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
  270. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +106 -18
  271. package/lib/solution/BaseSales/utils.d.ts +1 -1
  272. package/lib/solution/BaseSales/utils.js +54 -10
  273. package/lib/solution/BookingByStep/index.d.ts +1 -1
  274. package/lib/solution/BookingTicket/index.d.ts +271 -11
  275. package/lib/solution/BookingTicket/index.js +922 -29
  276. package/lib/solution/BookingTicket/types.d.ts +118 -1
  277. package/lib/solution/BookingTicket/types.js +11 -0
  278. package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +117 -0
  279. package/lib/solution/BookingTicket/utils/addProductDecision.js +318 -0
  280. package/lib/solution/BookingTicket/utils/addTimeAvailability.d.ts +35 -0
  281. package/lib/solution/BookingTicket/utils/addTimeAvailability.js +125 -0
  282. package/lib/solution/BookingTicket/utils/bookingStatus.d.ts +40 -0
  283. package/lib/solution/BookingTicket/utils/bookingStatus.js +44 -2
  284. package/lib/solution/BookingTicket/utils/cartView.d.ts +9 -1
  285. package/lib/solution/BookingTicket/utils/cartView.js +61 -6
  286. package/lib/solution/BookingTicket/utils/exampleData.d.ts +123 -0
  287. package/lib/solution/BookingTicket/utils/exampleData.js +0 -0
  288. package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.d.ts +185 -0
  289. package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +254 -0
  290. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +36 -0
  291. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +169 -0
  292. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +32 -0
  293. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +51 -0
  294. package/lib/solution/BookingTicket/utils/scan/index.d.ts +5 -0
  295. package/lib/solution/BookingTicket/utils/scan/index.js +17 -3
  296. package/lib/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
  297. package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +127 -0
  298. package/lib/solution/BookingTicket/utils/sessionCatalogStale.d.ts +23 -0
  299. package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +85 -0
  300. package/lib/solution/Checkout/index.d.ts +1 -0
  301. package/lib/solution/Checkout/index.js +1 -2
  302. package/lib/solution/RegisterAndLogin/config.js +2 -10
  303. package/lib/solution/ScanOrder/index.d.ts +9 -3
  304. package/lib/solution/ScanOrder/index.js +153 -70
  305. package/lib/solution/ScanOrder/types.d.ts +9 -5
  306. package/lib/solution/ScanOrder/utils.d.ts +1 -1
  307. package/lib/solution/ScanOrder/utils.js +83 -17
  308. package/lib/solution/VenueBooking/index.d.ts +5 -2
  309. package/lib/solution/VenueBooking/index.js +54 -17
  310. package/lib/solution/VenueBooking/sales-section-4-annotated.json +0 -2
  311. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +4 -0
  312. package/lib/solution/VenueBooking/utils/slotMerge.js +10 -0
  313. package/lib/types/index.d.ts +10 -0
  314. package/package.json +1 -1
  315. package/dist/solution/Checkout/appointmentDemo.json +0 -1
  316. package/lib/solution/Checkout/appointmentDemo.json +0 -1
@@ -37,9 +37,10 @@ import { applyDetailValueToProducts, applyPriceDataToProducts, applyI18nToProduc
37
37
  * IndexDB 存储名称
38
38
  */
39
39
  var INDEXDB_STORE_NAME = 'products';
40
-
41
40
  /** 商品同步防抖时间(毫秒) */
42
41
  var PRODUCT_SYNC_DEBOUNCE_MS = 10000;
42
+ /** silentRefresh 最小间隔,避免 preload 后立即全量重拉 */
43
+ var PRODUCT_SILENT_REFRESH_MIN_INTERVAL_MS = 30000;
43
44
 
44
45
  /**
45
46
  * Products 模块 - 用于获取和管理完整的商品详细数据
@@ -73,13 +74,19 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
73
74
  // 普通层 QuotationModule 桥接器:本地计算报价单价格,替代 /product/query/price
74
75
  _defineProperty(_assertThisInitialized(_this), "quotationPriceBridge", void 0);
75
76
  _defineProperty(_assertThisInitialized(_this), "quotationBridgeChannel", void 0);
76
- _defineProperty(_assertThisInitialized(_this), "quotationBridgeCustomerId", void 0);
77
+ _defineProperty(_assertThisInitialized(_this), "quotationBridgeLoadedKey", '');
77
78
  _defineProperty(_assertThisInitialized(_this), "quotationBridgeRefreshPromise", void 0);
78
79
  _defineProperty(_assertThisInitialized(_this), "quotationBridgeRefreshKey", void 0);
79
80
  // ---- 商品数据同步相关 ----
80
81
  _defineProperty(_assertThisInitialized(_this), "productDataSource", void 0);
81
82
  _defineProperty(_assertThisInitialized(_this), "pendingSyncMessages", []);
82
83
  _defineProperty(_assertThisInitialized(_this), "syncTimer", void 0);
84
+ /** 最近一次 SSE 全量拉取完成时间 */
85
+ _defineProperty(_assertThisInitialized(_this), "lastServerFullFetchAtMs", 0);
86
+ /** 最近一次 preload 完成时间(含 IndexDB 命中) */
87
+ _defineProperty(_assertThisInitialized(_this), "lastPreloadCompletedAtMs", 0);
88
+ /** IndexDB 写入串行队列,避免快照与 patch 并发交错 */
89
+ _defineProperty(_assertThisInitialized(_this), "productIndexDBSaveQueue", Promise.resolve());
83
90
  return _this;
84
91
  }
85
92
  _createClass(ProductsModule, [{
@@ -277,7 +284,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
277
284
  value: (function () {
278
285
  var _setupQuotationPriceBridge = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(params) {
279
286
  var _this$otherParams;
280
- var channel, quotation, _params$scheduleModul, _params$scheduleModul2, scheduleList, scheduleMap;
287
+ var channel, quotation, scheduleCache, hasLoadedScheduleList;
281
288
  return _regeneratorRuntime().wrap(function _callee3$(_context3) {
282
289
  while (1) switch (_context3.prev = _context3.next) {
283
290
  case 0:
@@ -301,14 +308,32 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
301
308
  this.quotationPriceBridge = quotation;
302
309
  case 10:
303
310
  if (params.scheduleModule) {
304
- scheduleList = ((_params$scheduleModul = (_params$scheduleModul2 = params.scheduleModule).getScheduleList) === null || _params$scheduleModul === void 0 ? void 0 : _params$scheduleModul.call(_params$scheduleModul2)) || [];
305
- scheduleMap = new Map(scheduleList.map(function (schedule) {
306
- return [schedule.id, schedule];
307
- }));
311
+ scheduleCache = new Map();
312
+ hasLoadedScheduleList = false;
308
313
  this.quotationPriceBridge.setScheduleResolver(function (id) {
309
- var _params$scheduleModul3, _params$scheduleModul4;
310
- if (scheduleMap.has(id)) return scheduleMap.get(id);
311
- var schedules = ((_params$scheduleModul3 = (_params$scheduleModul4 = params.scheduleModule).getScheduleByIds) === null || _params$scheduleModul3 === void 0 ? void 0 : _params$scheduleModul3.call(_params$scheduleModul4, [id])) || [];
314
+ var _params$scheduleModul3, _params$scheduleModul4, _params$scheduleModul5, _params$scheduleModul6;
315
+ var scheduleId = String(id);
316
+ if (scheduleCache.has(scheduleId)) return scheduleCache.get(scheduleId);
317
+ if (!hasLoadedScheduleList) {
318
+ var _params$scheduleModul, _params$scheduleModul2;
319
+ var scheduleList = ((_params$scheduleModul = (_params$scheduleModul2 = params.scheduleModule).getScheduleList) === null || _params$scheduleModul === void 0 ? void 0 : _params$scheduleModul.call(_params$scheduleModul2)) || [];
320
+ var _iterator = _createForOfIteratorHelper(scheduleList),
321
+ _step;
322
+ try {
323
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
324
+ var schedule = _step.value;
325
+ scheduleCache.set(String(schedule.id), schedule);
326
+ }
327
+ } catch (err) {
328
+ _iterator.e(err);
329
+ } finally {
330
+ _iterator.f();
331
+ }
332
+ hasLoadedScheduleList = true;
333
+ }
334
+ if (scheduleCache.has(scheduleId)) return scheduleCache.get(scheduleId);
335
+ var schedules = ((_params$scheduleModul3 = (_params$scheduleModul4 = params.scheduleModule).getScheduleListByIds) === null || _params$scheduleModul3 === void 0 ? void 0 : _params$scheduleModul3.call(_params$scheduleModul4, [id])) || ((_params$scheduleModul5 = (_params$scheduleModul6 = params.scheduleModule).getScheduleByIds) === null || _params$scheduleModul5 === void 0 ? void 0 : _params$scheduleModul5.call(_params$scheduleModul6, [id])) || [];
336
+ if (schedules[0]) scheduleCache.set(scheduleId, schedules[0]);
312
337
  return schedules[0];
313
338
  });
314
339
  }
@@ -336,7 +361,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
336
361
  value: (function () {
337
362
  var _refreshQuotationPriceBridge = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(params) {
338
363
  var _this3 = this;
339
- var customerId, refreshKey;
364
+ var refreshKey;
340
365
  return _regeneratorRuntime().wrap(function _callee4$(_context4) {
341
366
  while (1) switch (_context4.prev = _context4.next) {
342
367
  case 0:
@@ -346,37 +371,35 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
346
371
  }
347
372
  return _context4.abrupt("return");
348
373
  case 2:
349
- customerId = params && 'customer_id' in params ? params.customer_id : this.quotationBridgeCustomerId;
350
- refreshKey = this.getQuotationBridgeScopeKey(customerId);
374
+ refreshKey = this.getQuotationBridgeScopeKey();
351
375
  if (!(this.quotationBridgeRefreshPromise && this.quotationBridgeRefreshKey === refreshKey)) {
352
- _context4.next = 8;
376
+ _context4.next = 7;
353
377
  break;
354
378
  }
355
- _context4.next = 7;
379
+ _context4.next = 6;
356
380
  return this.quotationBridgeRefreshPromise;
357
- case 7:
381
+ case 6:
358
382
  return _context4.abrupt("return");
359
- case 8:
383
+ case 7:
360
384
  if (!this.quotationBridgeRefreshPromise) {
361
- _context4.next = 11;
385
+ _context4.next = 10;
362
386
  break;
363
387
  }
364
- _context4.next = 11;
388
+ _context4.next = 10;
365
389
  return this.quotationBridgeRefreshPromise;
366
- case 11:
390
+ case 10:
367
391
  this.quotationBridgeRefreshKey = refreshKey;
368
392
  this.quotationBridgeRefreshPromise = this.quotationPriceBridge.loadQuotations({
369
- channel: this.quotationBridgeChannel,
370
- customer_id: customerId
393
+ channel: this.quotationBridgeChannel
371
394
  }).then(function () {
372
- _this3.quotationBridgeCustomerId = customerId;
395
+ _this3.quotationBridgeLoadedKey = refreshKey;
373
396
  }).finally(function () {
374
397
  _this3.quotationBridgeRefreshPromise = undefined;
375
398
  _this3.quotationBridgeRefreshKey = undefined;
376
399
  });
377
- _context4.next = 15;
400
+ _context4.next = 14;
378
401
  return this.quotationBridgeRefreshPromise;
379
- case 15:
402
+ case 14:
380
403
  case "end":
381
404
  return _context4.stop();
382
405
  }
@@ -414,7 +437,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
414
437
  _context5.next = 7;
415
438
  return this.quotationBridgeRefreshPromise;
416
439
  case 7:
417
- if (!(this.getQuotationBridgeScopeKey(customerId) !== this.getQuotationBridgeScopeKey(this.quotationBridgeCustomerId))) {
440
+ if (!(this.getQuotationBridgeScopeKey() !== this.quotationBridgeLoadedKey)) {
418
441
  _context5.next = 10;
419
442
  break;
420
443
  }
@@ -435,23 +458,24 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
435
458
  }()
436
459
  }, {
437
460
  key: "getQuotationBridgeScopeKey",
438
- value: function getQuotationBridgeScopeKey(customerId) {
439
- return "".concat(this.quotationBridgeChannel || '', ":").concat(customerId !== null && customerId !== void 0 ? customerId : '');
461
+ value: function getQuotationBridgeScopeKey() {
462
+ return this.quotationBridgeChannel || '';
440
463
  }
441
464
  }, {
442
465
  key: "buildPriceDataFromQuotation",
443
466
  value: function buildPriceDataFromQuotation(product, datetime, customerId) {
444
- var _this$quotationPriceB, _ref2, _product$base_price;
467
+ var _this$quotationPriceB, _ref2, _ref3;
445
468
  var quotedPrice = (_this$quotationPriceB = this.quotationPriceBridge) === null || _this$quotationPriceB === void 0 ? void 0 : _this$quotationPriceB.getPriceForProduct({
446
469
  productId: product.id,
447
470
  datetime: datetime,
448
471
  customer_id: customerId
449
472
  });
450
473
  var productPrice = quotedPrice !== null && quotedPrice !== void 0 ? quotedPrice : product.price;
474
+ var productBasePrice = (_ref2 = (_ref3 = quotedPrice !== null && quotedPrice !== void 0 ? quotedPrice : product.base_price) !== null && _ref3 !== void 0 ? _ref3 : product.price) !== null && _ref2 !== void 0 ? _ref2 : 0;
451
475
  return {
452
476
  id: product.id,
453
477
  price: String(productPrice !== null && productPrice !== void 0 ? productPrice : 0),
454
- base_price: String((_ref2 = (_product$base_price = product.base_price) !== null && _product$base_price !== void 0 ? _product$base_price : product.price) !== null && _ref2 !== void 0 ? _ref2 : 0),
478
+ base_price: String(productBasePrice),
455
479
  variant: this.buildVariantPriceData(product, datetime, customerId),
456
480
  bundle_group: this.buildBundleGroupPriceData(product, datetime, customerId)
457
481
  };
@@ -462,15 +486,15 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
462
486
  var _this4 = this;
463
487
  if (!Array.isArray(product.variant)) return [];
464
488
  return product.variant.map(function (variant) {
465
- var _this4$quotationPrice, _ref3, _ref4, _ref5, _ref6, _ref7, _variant$base_price, _variant$product_id;
489
+ var _this4$quotationPrice, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _variant$product_id;
466
490
  var quotedPrice = (_this4$quotationPrice = _this4.quotationPriceBridge) === null || _this4$quotationPrice === void 0 ? void 0 : _this4$quotationPrice.getPriceForProduct({
467
491
  productId: product.id,
468
492
  variantId: Number(variant.id),
469
493
  datetime: datetime,
470
494
  customer_id: customerId
471
495
  });
472
- var price = (_ref3 = (_ref4 = quotedPrice !== null && quotedPrice !== void 0 ? quotedPrice : variant.price) !== null && _ref4 !== void 0 ? _ref4 : product.price) !== null && _ref3 !== void 0 ? _ref3 : 0;
473
- var basePrice = (_ref5 = (_ref6 = (_ref7 = (_variant$base_price = variant.base_price) !== null && _variant$base_price !== void 0 ? _variant$base_price : variant.price) !== null && _ref7 !== void 0 ? _ref7 : product.base_price) !== null && _ref6 !== void 0 ? _ref6 : product.price) !== null && _ref5 !== void 0 ? _ref5 : 0;
496
+ var price = (_ref4 = (_ref5 = quotedPrice !== null && quotedPrice !== void 0 ? quotedPrice : variant.price) !== null && _ref5 !== void 0 ? _ref5 : product.price) !== null && _ref4 !== void 0 ? _ref4 : 0;
497
+ var basePrice = (_ref6 = (_ref7 = (_ref8 = (_ref9 = quotedPrice !== null && quotedPrice !== void 0 ? quotedPrice : variant.base_price) !== null && _ref9 !== void 0 ? _ref9 : variant.price) !== null && _ref8 !== void 0 ? _ref8 : product.base_price) !== null && _ref7 !== void 0 ? _ref7 : product.price) !== null && _ref6 !== void 0 ? _ref6 : 0;
474
498
  return {
475
499
  id: Number(variant.id),
476
500
  product_id: Number((_variant$product_id = variant.product_id) !== null && _variant$product_id !== void 0 ? _variant$product_id : product.id),
@@ -488,7 +512,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
488
512
  return {
489
513
  id: Number(group.id),
490
514
  bundle_item: (group.bundle_item || []).map(function (item) {
491
- var _this5$quotationPrice, _ref8, _ref9, _item$base_price, _item$product_id, _item$group_id;
515
+ var _this5$quotationPrice, _ref10, _ref11, _ref12, _item$product_id, _item$group_id;
492
516
  var bundleProductId = Number(item.bundle_product_id);
493
517
  var bundleVariantId = Number(item.bundle_variant_id || 0);
494
518
  var quotedPrice = (_this5$quotationPrice = _this5.quotationPriceBridge) === null || _this5$quotationPrice === void 0 ? void 0 : _this5$quotationPrice.getPriceForProduct({
@@ -497,8 +521,8 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
497
521
  datetime: datetime,
498
522
  customer_id: customerId
499
523
  });
500
- var price = (_ref8 = quotedPrice !== null && quotedPrice !== void 0 ? quotedPrice : item.price) !== null && _ref8 !== void 0 ? _ref8 : 0;
501
- var basePrice = (_ref9 = (_item$base_price = item.base_price) !== null && _item$base_price !== void 0 ? _item$base_price : item.price) !== null && _ref9 !== void 0 ? _ref9 : 0;
524
+ var price = (_ref10 = quotedPrice !== null && quotedPrice !== void 0 ? quotedPrice : item.price) !== null && _ref10 !== void 0 ? _ref10 : 0;
525
+ var basePrice = (_ref11 = (_ref12 = quotedPrice !== null && quotedPrice !== void 0 ? quotedPrice : item.base_price) !== null && _ref12 !== void 0 ? _ref12 : item.price) !== null && _ref11 !== void 0 ? _ref11 : 0;
502
526
  return {
503
527
  id: Number(item.id),
504
528
  product_id: Number((_item$product_id = item.product_id) !== null && _item$product_id !== void 0 ? _item$product_id : product.id),
@@ -531,7 +555,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
531
555
  value: (function () {
532
556
  var _getProductsWithPrice = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(schedule_date, extraContext, options) {
533
557
  var _options$changedIds;
534
- var t0, scopedProductIds, cacheKey, scopedProductIdSet, changedIds, cachedProducts, updatedProducts, updatedMap, mergedCache, _iterator, _step, p, _iterator2, _step2, _p, errorMessage, result;
558
+ var t0, scopedProductIds, cacheKey, scopedProductIdSet, changedIds, cachedProducts, updatedProducts, updatedMap, mergedCache, _iterator2, _step2, p, _iterator3, _step3, _p, errorMessage, result;
535
559
  return _regeneratorRuntime().wrap(function _callee6$(_context6) {
536
560
  while (1) switch (_context6.prev = _context6.next) {
537
561
  case 0:
@@ -572,10 +596,10 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
572
596
  return [p.id, p];
573
597
  }));
574
598
  mergedCache = [];
575
- _iterator = _createForOfIteratorHelper(cachedProducts);
599
+ _iterator2 = _createForOfIteratorHelper(cachedProducts);
576
600
  try {
577
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
578
- p = _step.value;
601
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
602
+ p = _step2.value;
579
603
  if (updatedMap.has(p.id)) {
580
604
  mergedCache.push(updatedMap.get(p.id));
581
605
  updatedMap.delete(p.id);
@@ -585,20 +609,20 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
585
609
  }
586
610
  // 剩余的是新增商品(create 场景)
587
611
  } catch (err) {
588
- _iterator.e(err);
612
+ _iterator2.e(err);
589
613
  } finally {
590
- _iterator.f();
614
+ _iterator2.f();
591
615
  }
592
- _iterator2 = _createForOfIteratorHelper(updatedMap.values());
616
+ _iterator3 = _createForOfIteratorHelper(updatedMap.values());
593
617
  try {
594
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
595
- _p = _step2.value;
618
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
619
+ _p = _step3.value;
596
620
  mergedCache.push(_p);
597
621
  }
598
622
  } catch (err) {
599
- _iterator2.e(err);
623
+ _iterator3.e(err);
600
624
  } finally {
601
- _iterator2.f();
625
+ _iterator3.f();
602
626
  }
603
627
  this.productsPriceCache.set(cacheKey, mergedCache);
604
628
  this.logInfo('增量更新完成', {
@@ -833,25 +857,25 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
833
857
  }
834
858
  if (productIds.length === 0 && collectionIds.length === 0) return [];
835
859
  var result = new Set();
836
- var _iterator3 = _createForOfIteratorHelper(productIds),
837
- _step3;
860
+ var _iterator4 = _createForOfIteratorHelper(productIds),
861
+ _step4;
838
862
  try {
839
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
840
- var id = _step3.value;
863
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
864
+ var id = _step4.value;
841
865
  if (this.store.map.has(id)) result.add(id);
842
866
  }
843
867
  } catch (err) {
844
- _iterator3.e(err);
868
+ _iterator4.e(err);
845
869
  } finally {
846
- _iterator3.f();
870
+ _iterator4.f();
847
871
  }
848
872
  if (collectionIds.length === 0) return Array.from(result);
849
873
  var collectionIdSet = new Set(collectionIds);
850
- var _iterator4 = _createForOfIteratorHelper(this.getProductsRef()),
851
- _step4;
874
+ var _iterator5 = _createForOfIteratorHelper(this.getProductsRef()),
875
+ _step5;
852
876
  try {
853
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
854
- var product = _step4.value;
877
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
878
+ var product = _step5.value;
855
879
  if (result.has(product.id)) continue;
856
880
  if (!Array.isArray(product.collection)) continue;
857
881
  var isInCollection = product.collection.some(function (collection) {
@@ -860,9 +884,9 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
860
884
  if (isInCollection) result.add(product.id);
861
885
  }
862
886
  } catch (err) {
863
- _iterator4.e(err);
887
+ _iterator5.e(err);
864
888
  } finally {
865
- _iterator4.f();
889
+ _iterator5.f();
866
890
  }
867
891
  return Array.from(result);
868
892
  }
@@ -1100,17 +1124,18 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1100
1124
  duration: "".concat(Math.round(performance.now() - t0), "ms")
1101
1125
  });
1102
1126
  _context9.next = 15;
1103
- return this.saveProductsToIndexDB(list);
1127
+ return this.replaceProductsSnapshotInIndexDB(list, 'loadProductsByServer');
1104
1128
  case 15:
1105
- _context9.next = 17;
1129
+ this.lastServerFullFetchAtMs = Date.now();
1130
+ _context9.next = 18;
1106
1131
  return this.core.effects.emit(ProductsHooks.onProductsLoaded, list);
1107
- case 17:
1132
+ case 18:
1108
1133
  perfMark('loadProductsByServer', performance.now() - t0, {
1109
1134
  count: list.length
1110
1135
  });
1111
1136
  return _context9.abrupt("return", list);
1112
- case 21:
1113
- _context9.prev = 21;
1137
+ case 22:
1138
+ _context9.prev = 22;
1114
1139
  _context9.t0 = _context9["catch"](5);
1115
1140
  duration = Math.round(performance.now() - t0);
1116
1141
  errorMessage = _context9.t0 instanceof Error ? _context9.t0.message : String(_context9.t0);
@@ -1120,11 +1145,11 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1120
1145
  error: errorMessage
1121
1146
  });
1122
1147
  return _context9.abrupt("return", []);
1123
- case 28:
1148
+ case 29:
1124
1149
  case "end":
1125
1150
  return _context9.stop();
1126
1151
  }
1127
- }, _callee9, this, [[5, 21]]);
1152
+ }, _callee9, this, [[5, 22]]);
1128
1153
  }));
1129
1154
  function loadProductsByServer() {
1130
1155
  return _loadProductsByServer.apply(this, arguments);
@@ -1141,11 +1166,11 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1141
1166
  key: "fetchProductsByHttp",
1142
1167
  value: (function () {
1143
1168
  var _fetchProductsByHttp = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(params) {
1144
- var _ref10, _ref10$category_ids, category_ids, _ref10$product_ids, product_ids, _ref10$collection, collection, customer_id, cacheId, startTime, _this$otherParams3, _productsData$data, productsData, productList, duration, _duration2, errorMessage;
1169
+ var _ref13, _ref13$category_ids, category_ids, _ref13$product_ids, product_ids, _ref13$collection, collection, customer_id, cacheId, startTime, _this$otherParams3, _productsData$data, productsData, productList, duration, _duration2, errorMessage;
1145
1170
  return _regeneratorRuntime().wrap(function _callee10$(_context10) {
1146
1171
  while (1) switch (_context10.prev = _context10.next) {
1147
1172
  case 0:
1148
- _ref10 = params || {}, _ref10$category_ids = _ref10.category_ids, category_ids = _ref10$category_ids === void 0 ? [] : _ref10$category_ids, _ref10$product_ids = _ref10.product_ids, product_ids = _ref10$product_ids === void 0 ? [] : _ref10$product_ids, _ref10$collection = _ref10.collection, collection = _ref10$collection === void 0 ? [] : _ref10$collection, customer_id = _ref10.customer_id, cacheId = _ref10.cacheId;
1173
+ _ref13 = params || {}, _ref13$category_ids = _ref13.category_ids, category_ids = _ref13$category_ids === void 0 ? [] : _ref13$category_ids, _ref13$product_ids = _ref13.product_ids, product_ids = _ref13$product_ids === void 0 ? [] : _ref13$product_ids, _ref13$collection = _ref13.collection, collection = _ref13$collection === void 0 ? [] : _ref13$collection, customer_id = _ref13.customer_id, cacheId = _ref13.cacheId;
1149
1174
  this.logInfo('fetchProductsByHttp: 开始请求', {
1150
1175
  categoryIdsCount: category_ids.length,
1151
1176
  productIdsCount: product_ids.length,
@@ -1225,17 +1250,18 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1225
1250
  case 2:
1226
1251
  productList = _context11.sent;
1227
1252
  if (!(productList.length > 0)) {
1228
- _context11.next = 8;
1253
+ _context11.next = 9;
1229
1254
  break;
1230
1255
  }
1231
1256
  _context11.next = 6;
1232
- return this.saveProductsToIndexDB(productList);
1257
+ return this.replaceProductsSnapshotInIndexDB(productList, 'loadProductsByServerHttp');
1233
1258
  case 6:
1234
- _context11.next = 8;
1259
+ this.lastServerFullFetchAtMs = Date.now();
1260
+ _context11.next = 9;
1235
1261
  return this.core.effects.emit(ProductsHooks.onProductsLoaded, productList);
1236
- case 8:
1237
- return _context11.abrupt("return", productList);
1238
1262
  case 9:
1263
+ return _context11.abrupt("return", productList);
1264
+ case 10:
1239
1265
  case "end":
1240
1266
  return _context11.stop();
1241
1267
  }
@@ -1293,18 +1319,18 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1293
1319
  key: "getProductsRefByIds",
1294
1320
  value: function getProductsRefByIds(ids) {
1295
1321
  var products = [];
1296
- var _iterator5 = _createForOfIteratorHelper(ids),
1297
- _step5;
1322
+ var _iterator6 = _createForOfIteratorHelper(ids),
1323
+ _step6;
1298
1324
  try {
1299
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
1300
- var id = _step5.value;
1325
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
1326
+ var id = _step6.value;
1301
1327
  var product = this.store.map.get(id);
1302
1328
  if (product) products.push(product);
1303
1329
  }
1304
1330
  } catch (err) {
1305
- _iterator5.e(err);
1331
+ _iterator6.e(err);
1306
1332
  } finally {
1307
- _iterator5.f();
1333
+ _iterator6.f();
1308
1334
  }
1309
1335
  return products;
1310
1336
  }
@@ -1343,7 +1369,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1343
1369
  key: "removeProductsByIds",
1344
1370
  value: (function () {
1345
1371
  var _removeProductsByIds = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee14(ids) {
1346
- var idSet, _iterator6, _step6, _id, _iterator7, _step7, id, errorMessage, _iterator8, _step8, _step8$value, dateKey, cachedProducts;
1372
+ var idSet, _iterator7, _step7, _id, _iterator8, _step8, id, errorMessage, _iterator9, _step9, _step9$value, dateKey, cachedProducts;
1347
1373
  return _regeneratorRuntime().wrap(function _callee14$(_context14) {
1348
1374
  while (1) switch (_context14.prev = _context14.next) {
1349
1375
  case 0:
@@ -1355,31 +1381,31 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1355
1381
  this.store.list = this.store.list.filter(function (p) {
1356
1382
  return !idSet.has(p.id);
1357
1383
  });
1358
- _iterator6 = _createForOfIteratorHelper(ids);
1384
+ _iterator7 = _createForOfIteratorHelper(ids);
1359
1385
  try {
1360
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
1361
- _id = _step6.value;
1386
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
1387
+ _id = _step7.value;
1362
1388
  this.store.map.delete(_id);
1363
1389
  }
1364
1390
  } catch (err) {
1365
- _iterator6.e(err);
1391
+ _iterator7.e(err);
1366
1392
  } finally {
1367
- _iterator6.f();
1393
+ _iterator7.f();
1368
1394
  }
1369
1395
  if (!this.dbManager) {
1370
1396
  _context14.next = 30;
1371
1397
  break;
1372
1398
  }
1373
1399
  _context14.prev = 6;
1374
- _iterator7 = _createForOfIteratorHelper(ids);
1400
+ _iterator8 = _createForOfIteratorHelper(ids);
1375
1401
  _context14.prev = 8;
1376
- _iterator7.s();
1402
+ _iterator8.s();
1377
1403
  case 10:
1378
- if ((_step7 = _iterator7.n()).done) {
1404
+ if ((_step8 = _iterator8.n()).done) {
1379
1405
  _context14.next = 16;
1380
1406
  break;
1381
1407
  }
1382
- id = _step7.value;
1408
+ id = _step8.value;
1383
1409
  _context14.next = 14;
1384
1410
  return this.dbManager.delete(INDEXDB_STORE_NAME, id);
1385
1411
  case 14:
@@ -1391,10 +1417,10 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1391
1417
  case 18:
1392
1418
  _context14.prev = 18;
1393
1419
  _context14.t0 = _context14["catch"](8);
1394
- _iterator7.e(_context14.t0);
1420
+ _iterator8.e(_context14.t0);
1395
1421
  case 21:
1396
1422
  _context14.prev = 21;
1397
- _iterator7.f();
1423
+ _iterator8.f();
1398
1424
  return _context14.finish(21);
1399
1425
  case 24:
1400
1426
  _context14.next = 30;
@@ -1408,18 +1434,18 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1408
1434
  error: errorMessage
1409
1435
  });
1410
1436
  case 30:
1411
- _iterator8 = _createForOfIteratorHelper(this.productsPriceCache.entries());
1437
+ _iterator9 = _createForOfIteratorHelper(this.productsPriceCache.entries());
1412
1438
  try {
1413
- for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
1414
- _step8$value = _slicedToArray(_step8.value, 2), dateKey = _step8$value[0], cachedProducts = _step8$value[1];
1439
+ for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
1440
+ _step9$value = _slicedToArray(_step9.value, 2), dateKey = _step9$value[0], cachedProducts = _step9$value[1];
1415
1441
  this.productsPriceCache.set(dateKey, cachedProducts.filter(function (p) {
1416
1442
  return !idSet.has(p.id);
1417
1443
  }));
1418
1444
  }
1419
1445
  } catch (err) {
1420
- _iterator8.e(err);
1446
+ _iterator9.e(err);
1421
1447
  } finally {
1422
- _iterator8.f();
1448
+ _iterator9.f();
1423
1449
  }
1424
1450
  this.core.effects.emit(ProductsHooks.onProductsChanged, this.store.list);
1425
1451
  this.logInfo('removeProductsByIds 完成', {
@@ -1589,64 +1615,243 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1589
1615
  return loadProductsFromIndexDB;
1590
1616
  }()
1591
1617
  /**
1592
- * 保存商品数据到 IndexDB(平铺存储)
1593
- * @private
1618
+ * 串行执行商品 IndexDB 写入,避免快照替换与增量 patch 并发交错。
1619
+ *
1620
+ * @example
1621
+ * await this.runInProductIndexDBSaveQueue(async () => {
1622
+ * await this.dbManager.bulkUpdate(INDEXDB_STORE_NAME, products)
1623
+ * })
1594
1624
  */
1595
1625
  )
1596
1626
  }, {
1597
- key: "saveProductsToIndexDB",
1627
+ key: "runInProductIndexDBSaveQueue",
1598
1628
  value: (function () {
1599
- var _saveProductsToIndexDB = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee18(products) {
1600
- var t0, errorMessage;
1629
+ var _runInProductIndexDBSaveQueue = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee18(task) {
1630
+ var queuedTask;
1601
1631
  return _regeneratorRuntime().wrap(function _callee18$(_context18) {
1602
1632
  while (1) switch (_context18.prev = _context18.next) {
1633
+ case 0:
1634
+ queuedTask = this.productIndexDBSaveQueue.then(task, task);
1635
+ this.productIndexDBSaveQueue = queuedTask.then(function () {
1636
+ return undefined;
1637
+ }, function () {
1638
+ return undefined;
1639
+ });
1640
+ return _context18.abrupt("return", queuedTask);
1641
+ case 3:
1642
+ case "end":
1643
+ return _context18.stop();
1644
+ }
1645
+ }, _callee18, this);
1646
+ }));
1647
+ function runInProductIndexDBSaveQueue(_x19) {
1648
+ return _runInProductIndexDBSaveQueue.apply(this, arguments);
1649
+ }
1650
+ return runInProductIndexDBSaveQueue;
1651
+ }()
1652
+ /**
1653
+ * 全量快照写入 IndexDB:clear + bulkUpdate,仅用于 SSE/HTTP 全量拉取。
1654
+ *
1655
+ * @example
1656
+ * await this.replaceProductsSnapshotInIndexDB(list, 'loadProductsByServer')
1657
+ */
1658
+ )
1659
+ }, {
1660
+ key: "replaceProductsSnapshotInIndexDB",
1661
+ value: (function () {
1662
+ var _replaceProductsSnapshotInIndexDB = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee20(products, source) {
1663
+ var _this6 = this;
1664
+ var errorMessage;
1665
+ return _regeneratorRuntime().wrap(function _callee20$(_context20) {
1666
+ while (1) switch (_context20.prev = _context20.next) {
1603
1667
  case 0:
1604
1668
  if (this.dbManager) {
1605
- _context18.next = 3;
1669
+ _context20.next = 3;
1606
1670
  break;
1607
1671
  }
1608
- this.logWarning('saveProductsToIndexDB: dbManager 不可用');
1609
- return _context18.abrupt("return");
1672
+ this.logWarning('replaceProductsSnapshotInIndexDB: dbManager 不可用');
1673
+ return _context20.abrupt("return");
1610
1674
  case 3:
1611
- this.logInfo('开始保存商品数据到 IndexDB', {
1612
- productCount: products.length
1613
- });
1614
- _context18.prev = 4;
1615
- t0 = performance.now();
1616
- _context18.next = 8;
1617
- return this.dbManager.clear(INDEXDB_STORE_NAME);
1675
+ _context20.prev = 3;
1676
+ _context20.next = 6;
1677
+ return this.runInProductIndexDBSaveQueue( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee19() {
1678
+ var t0;
1679
+ return _regeneratorRuntime().wrap(function _callee19$(_context19) {
1680
+ while (1) switch (_context19.prev = _context19.next) {
1681
+ case 0:
1682
+ _this6.logInfo('replaceProductsSnapshotInIndexDB 开始', {
1683
+ source: source,
1684
+ productCount: products.length
1685
+ });
1686
+ t0 = performance.now();
1687
+ _context19.next = 4;
1688
+ return _this6.dbManager.clear(INDEXDB_STORE_NAME);
1689
+ case 4:
1690
+ if (!(products.length > 0)) {
1691
+ _context19.next = 7;
1692
+ break;
1693
+ }
1694
+ _context19.next = 7;
1695
+ return _this6.dbManager.bulkUpdate(INDEXDB_STORE_NAME, products);
1696
+ case 7:
1697
+ perfMark('replaceProductsSnapshotInIndexDB', performance.now() - t0, {
1698
+ count: products.length
1699
+ });
1700
+ _this6.logInfo('replaceProductsSnapshotInIndexDB 完成', {
1701
+ source: source,
1702
+ productCount: products.length
1703
+ });
1704
+ case 9:
1705
+ case "end":
1706
+ return _context19.stop();
1707
+ }
1708
+ }, _callee19);
1709
+ })));
1710
+ case 6:
1711
+ _context20.next = 12;
1712
+ break;
1618
1713
  case 8:
1619
- _context18.next = 10;
1620
- return this.dbManager.bulkUpdate(INDEXDB_STORE_NAME, products);
1621
- case 10:
1622
- perfMark('saveProductsToIndexDB', performance.now() - t0, {
1623
- count: products.length
1714
+ _context20.prev = 8;
1715
+ _context20.t0 = _context20["catch"](3);
1716
+ errorMessage = _context20.t0 instanceof Error ? _context20.t0.message : String(_context20.t0);
1717
+ this.logError('全量保存商品到 IndexDB 失败', {
1718
+ source: source,
1719
+ productCount: products.length,
1720
+ error: errorMessage
1624
1721
  });
1625
- console.log("[Products] \u5DF2\u5C06 ".concat(products.length, " \u4E2A\u5546\u54C1\u5E73\u94FA\u4FDD\u5B58\u5230 IndexDB"));
1626
- this.logInfo('商品数据已保存到 IndexDB', {
1627
- productCount: products.length
1722
+ case 12:
1723
+ case "end":
1724
+ return _context20.stop();
1725
+ }
1726
+ }, _callee20, this, [[3, 8]]);
1727
+ }));
1728
+ function replaceProductsSnapshotInIndexDB(_x20, _x21) {
1729
+ return _replaceProductsSnapshotInIndexDB.apply(this, arguments);
1730
+ }
1731
+ return replaceProductsSnapshotInIndexDB;
1732
+ }()
1733
+ /**
1734
+ * 增量 upsert 商品到 IndexDB,不清空表;用于 pubsub 批次合并后的变更商品。
1735
+ *
1736
+ * @example
1737
+ * await this.patchProductsInIndexDB(changedProducts, 'pubsub.processProductSyncMessages', mergeActions)
1738
+ */
1739
+ )
1740
+ }, {
1741
+ key: "patchProductsInIndexDB",
1742
+ value: (function () {
1743
+ var _patchProductsInIndexDB = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee22(products, source) {
1744
+ var _this7 = this;
1745
+ var mergeActions,
1746
+ validProducts,
1747
+ errorMessage,
1748
+ _args22 = arguments;
1749
+ return _regeneratorRuntime().wrap(function _callee22$(_context22) {
1750
+ while (1) switch (_context22.prev = _context22.next) {
1751
+ case 0:
1752
+ mergeActions = _args22.length > 2 && _args22[2] !== undefined ? _args22[2] : {};
1753
+ if (!(!this.dbManager || products.length === 0)) {
1754
+ _context22.next = 3;
1755
+ break;
1756
+ }
1757
+ return _context22.abrupt("return");
1758
+ case 3:
1759
+ validProducts = products.filter(function (p) {
1760
+ return (p === null || p === void 0 ? void 0 : p.id) !== undefined && (p === null || p === void 0 ? void 0 : p.id) !== null;
1628
1761
  });
1629
- _context18.next = 20;
1762
+ if (!(validProducts.length === 0)) {
1763
+ _context22.next = 6;
1764
+ break;
1765
+ }
1766
+ return _context22.abrupt("return");
1767
+ case 6:
1768
+ _context22.prev = 6;
1769
+ _context22.next = 9;
1770
+ return this.runInProductIndexDBSaveQueue( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee21() {
1771
+ var t0, _iterator10, _step10, product;
1772
+ return _regeneratorRuntime().wrap(function _callee21$(_context21) {
1773
+ while (1) switch (_context21.prev = _context21.next) {
1774
+ case 0:
1775
+ _this7.logInfo('patchProductsInIndexDB 开始', {
1776
+ source: source,
1777
+ count: validProducts.length
1778
+ });
1779
+ t0 = performance.now();
1780
+ if (!(typeof _this7.dbManager.bulkUpdate === 'function')) {
1781
+ _context21.next = 7;
1782
+ break;
1783
+ }
1784
+ _context21.next = 5;
1785
+ return _this7.dbManager.bulkUpdate(INDEXDB_STORE_NAME, validProducts);
1786
+ case 5:
1787
+ _context21.next = 25;
1788
+ break;
1789
+ case 7:
1790
+ if (!(typeof _this7.dbManager.update === 'function')) {
1791
+ _context21.next = 25;
1792
+ break;
1793
+ }
1794
+ _iterator10 = _createForOfIteratorHelper(validProducts);
1795
+ _context21.prev = 9;
1796
+ _iterator10.s();
1797
+ case 11:
1798
+ if ((_step10 = _iterator10.n()).done) {
1799
+ _context21.next = 17;
1800
+ break;
1801
+ }
1802
+ product = _step10.value;
1803
+ _context21.next = 15;
1804
+ return _this7.dbManager.update(INDEXDB_STORE_NAME, product);
1805
+ case 15:
1806
+ _context21.next = 11;
1807
+ break;
1808
+ case 17:
1809
+ _context21.next = 22;
1810
+ break;
1811
+ case 19:
1812
+ _context21.prev = 19;
1813
+ _context21.t0 = _context21["catch"](9);
1814
+ _iterator10.e(_context21.t0);
1815
+ case 22:
1816
+ _context21.prev = 22;
1817
+ _iterator10.f();
1818
+ return _context21.finish(22);
1819
+ case 25:
1820
+ perfMark('patchProductsInIndexDB', performance.now() - t0, {
1821
+ count: validProducts.length
1822
+ });
1823
+ _this7.logInfo('patchProductsInIndexDB 完成', {
1824
+ source: source,
1825
+ count: validProducts.length
1826
+ });
1827
+ case 27:
1828
+ case "end":
1829
+ return _context21.stop();
1830
+ }
1831
+ }, _callee21, null, [[9, 19, 22, 25]]);
1832
+ })));
1833
+ case 9:
1834
+ _context22.next = 15;
1630
1835
  break;
1631
- case 15:
1632
- _context18.prev = 15;
1633
- _context18.t0 = _context18["catch"](4);
1634
- errorMessage = _context18.t0 instanceof Error ? _context18.t0.message : String(_context18.t0);
1635
- console.error('[Products] 保存数据到 IndexDB 失败:', _context18.t0);
1636
- this.logError('保存数据到 IndexDB 失败', {
1637
- productCount: products.length,
1638
- error: errorMessage
1836
+ case 11:
1837
+ _context22.prev = 11;
1838
+ _context22.t0 = _context22["catch"](6);
1839
+ errorMessage = _context22.t0 instanceof Error ? _context22.t0.message : String(_context22.t0);
1840
+ this.logError('增量保存商品到 IndexDB 失败', {
1841
+ source: source,
1842
+ error: errorMessage,
1843
+ productCount: validProducts.length
1639
1844
  });
1640
- case 20:
1845
+ case 15:
1641
1846
  case "end":
1642
- return _context18.stop();
1847
+ return _context22.stop();
1643
1848
  }
1644
- }, _callee18, this, [[4, 15]]);
1849
+ }, _callee22, this, [[6, 11]]);
1645
1850
  }));
1646
- function saveProductsToIndexDB(_x19) {
1647
- return _saveProductsToIndexDB.apply(this, arguments);
1851
+ function patchProductsInIndexDB(_x22, _x23) {
1852
+ return _patchProductsInIndexDB.apply(this, arguments);
1648
1853
  }
1649
- return saveProductsToIndexDB;
1854
+ return patchProductsInIndexDB;
1650
1855
  }()
1651
1856
  /**
1652
1857
  * 同步更新商品 Map 缓存
@@ -1659,17 +1864,17 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1659
1864
  value: function syncProductsMap() {
1660
1865
  var t0 = performance.now();
1661
1866
  this.store.map.clear();
1662
- var _iterator9 = _createForOfIteratorHelper(this.store.list),
1663
- _step9;
1867
+ var _iterator11 = _createForOfIteratorHelper(this.store.list),
1868
+ _step11;
1664
1869
  try {
1665
- for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
1666
- var product = _step9.value;
1870
+ for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
1871
+ var product = _step11.value;
1667
1872
  this.store.map.set(product.id, product);
1668
1873
  }
1669
1874
  } catch (err) {
1670
- _iterator9.e(err);
1875
+ _iterator11.e(err);
1671
1876
  } finally {
1672
- _iterator9.f();
1877
+ _iterator11.f();
1673
1878
  }
1674
1879
  perfMark('syncProductsMap', performance.now() - t0, {
1675
1880
  count: this.store.map.size
@@ -1683,26 +1888,26 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1683
1888
  }, {
1684
1889
  key: "preload",
1685
1890
  value: (function () {
1686
- var _preload = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee19() {
1891
+ var _preload = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee23() {
1687
1892
  var _products$length3;
1688
1893
  var tTotal, _cachedData$length, tIndexDB, cachedData, tSync, errorMessage, tServer, products, _tSync;
1689
- return _regeneratorRuntime().wrap(function _callee19$(_context19) {
1690
- while (1) switch (_context19.prev = _context19.next) {
1894
+ return _regeneratorRuntime().wrap(function _callee23$(_context23) {
1895
+ while (1) switch (_context23.prev = _context23.next) {
1691
1896
  case 0:
1692
1897
  console.log('[Products] 开始预加载数据...');
1693
1898
  tTotal = performance.now();
1694
1899
  this.logInfo('开始预加载数据');
1695
- _context19.prev = 3;
1900
+ _context23.prev = 3;
1696
1901
  tIndexDB = performance.now();
1697
- _context19.next = 7;
1902
+ _context23.next = 7;
1698
1903
  return this.loadProductsFromIndexDB();
1699
1904
  case 7:
1700
- cachedData = _context19.sent;
1905
+ cachedData = _context23.sent;
1701
1906
  perfMark('preload.loadFromIndexDB', performance.now() - tIndexDB, {
1702
1907
  count: (_cachedData$length = cachedData === null || cachedData === void 0 ? void 0 : cachedData.length) !== null && _cachedData$length !== void 0 ? _cachedData$length : 0
1703
1908
  });
1704
1909
  if (!(cachedData && cachedData.length > 0)) {
1705
- _context19.next = 19;
1910
+ _context23.next = 20;
1706
1911
  break;
1707
1912
  }
1708
1913
  console.log("[Products] \u4ECE IndexDB \u52A0\u8F7D\u4E86 ".concat(cachedData.length, " \u4E2A\u5546\u54C1"));
@@ -1723,26 +1928,27 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1723
1928
  duration: "".concat(Math.round(performance.now() - tTotal), "ms"),
1724
1929
  source: 'IndexDB'
1725
1930
  });
1726
- return _context19.abrupt("return");
1727
- case 19:
1931
+ this.lastPreloadCompletedAtMs = Date.now();
1932
+ return _context23.abrupt("return");
1933
+ case 20:
1728
1934
  console.log('[Products] IndexDB 中没有缓存数据,从服务器加载...');
1729
1935
  this.logInfo('IndexDB 中没有缓存数据,准备从服务器加载');
1730
- _context19.next = 28;
1936
+ _context23.next = 29;
1731
1937
  break;
1732
- case 23:
1733
- _context19.prev = 23;
1734
- _context19.t0 = _context19["catch"](3);
1735
- errorMessage = _context19.t0 instanceof Error ? _context19.t0.message : String(_context19.t0);
1736
- console.warn('[Products] 从 IndexDB 加载数据失败:', _context19.t0);
1938
+ case 24:
1939
+ _context23.prev = 24;
1940
+ _context23.t0 = _context23["catch"](3);
1941
+ errorMessage = _context23.t0 instanceof Error ? _context23.t0.message : String(_context23.t0);
1942
+ console.warn('[Products] 从 IndexDB 加载数据失败:', _context23.t0);
1737
1943
  this.logWarning('从 IndexDB 加载数据失败,准备从服务器加载', {
1738
1944
  error: errorMessage
1739
1945
  });
1740
- case 28:
1946
+ case 29:
1741
1947
  tServer = performance.now();
1742
- _context19.next = 31;
1948
+ _context23.next = 32;
1743
1949
  return this.loadProductsByServer();
1744
- case 31:
1745
- products = _context19.sent;
1950
+ case 32:
1951
+ products = _context23.sent;
1746
1952
  perfMark('preload.loadFromServer', performance.now() - tServer, {
1747
1953
  count: (_products$length3 = products === null || products === void 0 ? void 0 : products.length) !== null && _products$length3 !== void 0 ? _products$length3 : 0
1748
1954
  });
@@ -1764,6 +1970,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1764
1970
  duration: "".concat(Math.round(performance.now() - tTotal), "ms"),
1765
1971
  source: 'Server'
1766
1972
  });
1973
+ this.lastPreloadCompletedAtMs = Date.now();
1767
1974
  } else {
1768
1975
  perfMark('preload(empty)', performance.now() - tTotal, {
1769
1976
  source: 'empty'
@@ -1772,11 +1979,11 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1772
1979
  duration: "".concat(Math.round(performance.now() - tTotal), "ms")
1773
1980
  });
1774
1981
  }
1775
- case 34:
1982
+ case 35:
1776
1983
  case "end":
1777
- return _context19.stop();
1984
+ return _context23.stop();
1778
1985
  }
1779
- }, _callee19, this, [[3, 23]]);
1986
+ }, _callee23, this, [[3, 24]]);
1780
1987
  }));
1781
1988
  function preload() {
1782
1989
  return _preload.apply(this, arguments);
@@ -1811,7 +2018,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1811
2018
  }, {
1812
2019
  key: "setupProductSync",
1813
2020
  value: function setupProductSync() {
1814
- var _this6 = this;
2021
+ var _this8 = this;
1815
2022
  if (!this.productDataSource) {
1816
2023
  this.logWarning('setupProductSync: ProductDataSource 不可用,跳过同步初始化');
1817
2024
  return;
@@ -1821,30 +2028,30 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1821
2028
  var data = (message === null || message === void 0 ? void 0 : message.data) || message;
1822
2029
  if (!data) return;
1823
2030
  console.log("[ProductsModule] \u6536\u5230\u540C\u6B65\u6D88\u606F [".concat(channelKey, "]:"), data);
1824
- _this6.logInfo('收到同步消息', {
2031
+ _this8.logInfo('收到同步消息', {
1825
2032
  channelKey: channelKey,
1826
2033
  action: data.action,
1827
2034
  id: data.id,
1828
2035
  action_filed: data.action_filed
1829
2036
  });
1830
- _this6.pendingSyncMessages.push(_objectSpread(_objectSpread({}, data), {}, {
2037
+ _this8.pendingSyncMessages.push(_objectSpread(_objectSpread({}, data), {}, {
1831
2038
  _channelKey: channelKey
1832
2039
  }));
1833
- if (_this6.syncTimer) {
1834
- clearTimeout(_this6.syncTimer);
2040
+ if (_this8.syncTimer) {
2041
+ clearTimeout(_this8.syncTimer);
1835
2042
  }
1836
- _this6.syncTimer = setTimeout(function () {
1837
- _this6.processProductSyncMessages();
2043
+ _this8.syncTimer = setTimeout(function () {
2044
+ _this8.processProductSyncMessages();
1838
2045
  }, PRODUCT_SYNC_DEBOUNCE_MS);
1839
2046
  };
1840
2047
  };
1841
2048
  this.productDataSource.run({
1842
2049
  pubsub: {
1843
2050
  callback: function callback(res) {
1844
- console.log('sse_products_callback', res);
1845
- _this6.logInfo('sse_products_callback: 收到同步消息', {
1846
- data: res === null || res === void 0 ? void 0 : res.data
1847
- });
2051
+ // console.log('sse_products_callback', res)
2052
+ // this.logInfo('sse_products_callback: 收到同步消息', {
2053
+ // data: res?.data,
2054
+ // });
1848
2055
  if (!(res !== null && res !== void 0 && res.data)) return;
1849
2056
  var data = res.data;
1850
2057
  var channelKey = data.module || 'product';
@@ -1852,7 +2059,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1852
2059
  }
1853
2060
  }
1854
2061
  }).catch(function (err) {
1855
- _this6.logError('setupProductSync: DataSource run 出错', {
2062
+ _this8.logError('setupProductSync: DataSource run 出错', {
1856
2063
  error: err instanceof Error ? err.message : String(err)
1857
2064
  });
1858
2065
  });
@@ -1880,18 +2087,18 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1880
2087
  }, {
1881
2088
  key: "processProductSyncMessages",
1882
2089
  value: (function () {
1883
- var _processProductSyncMessages = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee20() {
1884
- var messages, deleteIds, bodyUpdates, sseRefreshIds, priceRefreshIds, shouldClearPriceCache, _iterator10, _step10, msg, channelKey, _msg$relation_product, _msg$change_types, _msg$ids2, _msg$ids, ids, bodyId, _bodyId, _msg$relation_product2, _msg$relation_product3, uniqueDeleteIds, uniqueSSEIds, uniquePriceIds, freshProducts, allChangedIds, hasChanges, errorMessage;
1885
- return _regeneratorRuntime().wrap(function _callee20$(_context20) {
1886
- while (1) switch (_context20.prev = _context20.next) {
2090
+ var _processProductSyncMessages = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee24() {
2091
+ var messages, deleteIds, bodyUpdates, sseRefreshIds, priceRefreshIds, shouldClearPriceCache, _iterator12, _step12, msg, channelKey, _msg$relation_product, _msg$change_types, _msg$ids2, _msg$ids, ids, bodyId, _bodyId, _msg$relation_product2, _msg$relation_product3, uniqueDeleteIds, uniqueSSEIds, uniquePriceIds, patchProductMap, patchMergeActions, storeMutated, bodyResult, _iterator13, _step13, product, freshProducts, mergeResult, _iterator14, _step14, _product, patchProducts, allChangedIds, hasChanges, errorMessage;
2092
+ return _regeneratorRuntime().wrap(function _callee24$(_context24) {
2093
+ while (1) switch (_context24.prev = _context24.next) {
1887
2094
  case 0:
1888
2095
  messages = _toConsumableArray(this.pendingSyncMessages);
1889
2096
  this.pendingSyncMessages = [];
1890
2097
  if (!(messages.length === 0)) {
1891
- _context20.next = 4;
2098
+ _context24.next = 4;
1892
2099
  break;
1893
2100
  }
1894
- return _context20.abrupt("return");
2101
+ return _context24.abrupt("return");
1895
2102
  case 4:
1896
2103
  this.logInfo('processProductSyncMessages: 开始处理', {
1897
2104
  count: messages.length
@@ -1901,18 +2108,18 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1901
2108
  sseRefreshIds = [];
1902
2109
  priceRefreshIds = [];
1903
2110
  shouldClearPriceCache = false;
1904
- _iterator10 = _createForOfIteratorHelper(messages);
1905
- _context20.prev = 11;
1906
- _iterator10.s();
2111
+ _iterator12 = _createForOfIteratorHelper(messages);
2112
+ _context24.prev = 11;
2113
+ _iterator12.s();
1907
2114
  case 13:
1908
- if ((_step10 = _iterator10.n()).done) {
1909
- _context20.next = 36;
2115
+ if ((_step12 = _iterator12.n()).done) {
2116
+ _context24.next = 36;
1910
2117
  break;
1911
2118
  }
1912
- msg = _step10.value;
2119
+ msg = _step12.value;
1913
2120
  channelKey = msg._channelKey || msg.module || 'product';
1914
2121
  if (!(channelKey === 'product')) {
1915
- _context20.next = 33;
2122
+ _context24.next = 33;
1916
2123
  break;
1917
2124
  }
1918
2125
  if ((_msg$relation_product = msg.relation_product_ids) !== null && _msg$relation_product !== void 0 && _msg$relation_product.length) {
@@ -1920,14 +2127,14 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1920
2127
  }
1921
2128
  // 1. 删除场景:operation === 'delete' 或 action === 'delete'
1922
2129
  if (!(msg.operation === 'delete' || msg.action === 'delete')) {
1923
- _context20.next = 21;
2130
+ _context24.next = 21;
1924
2131
  break;
1925
2132
  }
1926
2133
  if ((_msg$ids = msg.ids) !== null && _msg$ids !== void 0 && _msg$ids.length) deleteIds.push.apply(deleteIds, _toConsumableArray(msg.ids));else if (msg.id) deleteIds.push(msg.id);
1927
- return _context20.abrupt("continue", 34);
2134
+ return _context24.abrupt("continue", 34);
1928
2135
  case 21:
1929
2136
  if (!((_msg$change_types = msg.change_types) !== null && _msg$change_types !== void 0 && _msg$change_types.includes('price'))) {
1930
- _context20.next = 26;
2137
+ _context24.next = 26;
1931
2138
  break;
1932
2139
  }
1933
2140
  ids = msg.ids || (msg.id ? [msg.id] : []);
@@ -1936,15 +2143,15 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1936
2143
  bodyId = msg.body.id;
1937
2144
  if (bodyId) bodyUpdates.set(bodyId, msg.body);
1938
2145
  }
1939
- return _context20.abrupt("continue", 34);
2146
+ return _context24.abrupt("continue", 34);
1940
2147
  case 26:
1941
2148
  if (!msg.body) {
1942
- _context20.next = 30;
2149
+ _context24.next = 30;
1943
2150
  break;
1944
2151
  }
1945
2152
  _bodyId = msg.body.id || msg.id;
1946
2153
  if (_bodyId) bodyUpdates.set(_bodyId, msg.body);
1947
- return _context20.abrupt("continue", 34);
2154
+ return _context24.abrupt("continue", 34);
1948
2155
  case 30:
1949
2156
  // 4. 其他情况(有 ids 无 body 无 change_types)→ SSE 拉取
1950
2157
  if ((_msg$ids2 = msg.ids) !== null && _msg$ids2 !== void 0 && _msg$ids2.length) {
@@ -1952,7 +2159,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1952
2159
  } else if (msg.id) {
1953
2160
  sseRefreshIds.push(msg.id);
1954
2161
  }
1955
- _context20.next = 34;
2162
+ _context24.next = 34;
1956
2163
  break;
1957
2164
  case 33:
1958
2165
  if (channelKey === 'product_quotation') {
@@ -1967,57 +2174,111 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1967
2174
  }
1968
2175
  }
1969
2176
  case 34:
1970
- _context20.next = 13;
2177
+ _context24.next = 13;
1971
2178
  break;
1972
2179
  case 36:
1973
- _context20.next = 41;
2180
+ _context24.next = 41;
1974
2181
  break;
1975
2182
  case 38:
1976
- _context20.prev = 38;
1977
- _context20.t0 = _context20["catch"](11);
1978
- _iterator10.e(_context20.t0);
2183
+ _context24.prev = 38;
2184
+ _context24.t0 = _context24["catch"](11);
2185
+ _iterator12.e(_context24.t0);
1979
2186
  case 41:
1980
- _context20.prev = 41;
1981
- _iterator10.f();
1982
- return _context20.finish(41);
2187
+ _context24.prev = 41;
2188
+ _iterator12.f();
2189
+ return _context24.finish(41);
1983
2190
  case 44:
1984
2191
  uniqueDeleteIds = _toConsumableArray(new Set(deleteIds));
1985
2192
  uniqueSSEIds = _toConsumableArray(new Set(sseRefreshIds));
1986
2193
  uniquePriceIds = _toConsumableArray(new Set(priceRefreshIds)); // 1. 处理删除
1987
2194
  if (!(uniqueDeleteIds.length > 0)) {
1988
- _context20.next = 50;
2195
+ _context24.next = 50;
1989
2196
  break;
1990
2197
  }
1991
- _context20.next = 50;
2198
+ _context24.next = 50;
1992
2199
  return this.removeProductsByIds(uniqueDeleteIds);
1993
2200
  case 50:
2201
+ /** 本批次待 patch 的商品(按 id 去重,SSE 覆盖 body) */
2202
+ patchProductMap = new Map();
2203
+ patchMergeActions = {};
2204
+ storeMutated = uniqueDeleteIds.length > 0; // 2. 处理 body 直接覆盖(仅内存,IndexDB 批次末统一 patch)
1994
2205
  if (!(bodyUpdates.size > 0)) {
1995
- _context20.next = 53;
2206
+ _context24.next = 60;
1996
2207
  break;
1997
2208
  }
1998
- _context20.next = 53;
1999
- return this.applyBodyUpdatesToStore(bodyUpdates);
2000
- case 53:
2209
+ _context24.next = 56;
2210
+ return this.applyBodyUpdatesToStore(bodyUpdates, {
2211
+ skipIndexDB: true,
2212
+ skipEmit: true
2213
+ });
2214
+ case 56:
2215
+ bodyResult = _context24.sent;
2216
+ _iterator13 = _createForOfIteratorHelper(bodyResult.changedProducts);
2217
+ try {
2218
+ for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
2219
+ product = _step13.value;
2220
+ patchProductMap.set(product.id, product);
2221
+ patchMergeActions[product.id] = bodyResult.mergeActions[product.id];
2222
+ }
2223
+ } catch (err) {
2224
+ _iterator13.e(err);
2225
+ } finally {
2226
+ _iterator13.f();
2227
+ }
2228
+ storeMutated = true;
2229
+ case 60:
2230
+ // 3. 处理 SSE 增量拉取(仅内存,IndexDB 批次末统一 patch)
2231
+ freshProducts = [];
2001
2232
  if (!(uniqueSSEIds.length > 0)) {
2002
- _context20.next = 61;
2233
+ _context24.next = 73;
2003
2234
  break;
2004
2235
  }
2005
- _context20.next = 56;
2236
+ _context24.next = 64;
2006
2237
  return this.fetchProductsBySSE(uniqueSSEIds);
2007
- case 56:
2008
- freshProducts = _context20.sent;
2238
+ case 64:
2239
+ freshProducts = _context24.sent;
2009
2240
  if (!(freshProducts.length > 0)) {
2010
- _context20.next = 60;
2241
+ _context24.next = 72;
2011
2242
  break;
2012
2243
  }
2013
- _context20.next = 60;
2014
- return this.mergeProductsToStore(freshProducts);
2015
- case 60:
2244
+ _context24.next = 68;
2245
+ return this.mergeProductsToStore(freshProducts, {
2246
+ skipIndexDB: true,
2247
+ skipEmit: true
2248
+ });
2249
+ case 68:
2250
+ mergeResult = _context24.sent;
2251
+ _iterator14 = _createForOfIteratorHelper(mergeResult.changedProducts);
2252
+ try {
2253
+ for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
2254
+ _product = _step14.value;
2255
+ patchProductMap.set(_product.id, _product);
2256
+ patchMergeActions[_product.id] = mergeResult.mergeActions[_product.id];
2257
+ }
2258
+ } catch (err) {
2259
+ _iterator14.e(err);
2260
+ } finally {
2261
+ _iterator14.f();
2262
+ }
2263
+ storeMutated = true;
2264
+ case 72:
2016
2265
  this.logInfo('processProductSyncMessages: SSE 增量更新完成123', {
2017
2266
  requestedCount: uniqueSSEIds.length,
2018
2267
  receivedCount: freshProducts.length
2019
2268
  });
2020
- case 61:
2269
+ case 73:
2270
+ patchProducts = _toConsumableArray(patchProductMap.values());
2271
+ if (!(patchProducts.length > 0)) {
2272
+ _context24.next = 77;
2273
+ break;
2274
+ }
2275
+ _context24.next = 77;
2276
+ return this.patchProductsInIndexDB(patchProducts, 'pubsub.processProductSyncMessages', patchMergeActions);
2277
+ case 77:
2278
+ if (storeMutated) {
2279
+ this.core.effects.emit(ProductsHooks.onProductsChanged, this.store.list);
2280
+ }
2281
+
2021
2282
  // 收集所有非 delete 的变更 IDs(body + SSE + price),用于增量更新价格缓存
2022
2283
  allChangedIds = _toConsumableArray(new Set([].concat(_toConsumableArray(Array.from(bodyUpdates.keys())), _toConsumableArray(uniqueSSEIds), _toConsumableArray(uniquePriceIds))));
2023
2284
  this.logInfo('processProductSyncMessages: 处理完成123', {
@@ -2030,41 +2291,41 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
2030
2291
  });
2031
2292
  hasChanges = uniqueDeleteIds.length > 0 || allChangedIds.length > 0 || shouldClearPriceCache;
2032
2293
  if (hasChanges) {
2033
- _context20.next = 67;
2294
+ _context24.next = 84;
2034
2295
  break;
2035
2296
  }
2036
2297
  this.logInfo('processProductSyncMessages: 没有变更,不触发 onProductsSyncCompleted');
2037
- return _context20.abrupt("return");
2038
- case 67:
2298
+ return _context24.abrupt("return");
2299
+ case 84:
2039
2300
  if (!shouldClearPriceCache) {
2040
- _context20.next = 78;
2301
+ _context24.next = 95;
2041
2302
  break;
2042
2303
  }
2043
- _context20.prev = 68;
2044
- _context20.next = 71;
2304
+ _context24.prev = 85;
2305
+ _context24.next = 88;
2045
2306
  return this.refreshQuotationPriceBridge();
2046
- case 71:
2047
- _context20.next = 77;
2307
+ case 88:
2308
+ _context24.next = 94;
2048
2309
  break;
2049
- case 73:
2050
- _context20.prev = 73;
2051
- _context20.t1 = _context20["catch"](68);
2052
- errorMessage = _context20.t1 instanceof Error ? _context20.t1.message : String(_context20.t1);
2310
+ case 90:
2311
+ _context24.prev = 90;
2312
+ _context24.t1 = _context24["catch"](85);
2313
+ errorMessage = _context24.t1 instanceof Error ? _context24.t1.message : String(_context24.t1);
2053
2314
  this.logError('报价单桥接刷新失败,将继续清理价格缓存', {
2054
2315
  error: errorMessage
2055
2316
  });
2056
- case 77:
2317
+ case 94:
2057
2318
  this.clearPriceCache();
2058
- case 78:
2059
- _context20.next = 80;
2319
+ case 95:
2320
+ _context24.next = 97;
2060
2321
  return this.core.effects.emit(ProductsHooks.onProductsSyncCompleted, {
2061
2322
  changedIds: allChangedIds
2062
2323
  });
2063
- case 80:
2324
+ case 97:
2064
2325
  case "end":
2065
- return _context20.stop();
2326
+ return _context24.stop();
2066
2327
  }
2067
- }, _callee20, this, [[11, 38, 41, 44], [68, 73]]);
2328
+ }, _callee24, this, [[11, 38, 41, 44], [85, 90]]);
2068
2329
  }));
2069
2330
  function processProductSyncMessages() {
2070
2331
  return _processProductSyncMessages.apply(this, arguments);
@@ -2079,25 +2340,25 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
2079
2340
  }, {
2080
2341
  key: "fetchProductsBySSE",
2081
2342
  value: (function () {
2082
- var _fetchProductsBySSE = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee21(ids) {
2343
+ var _fetchProductsBySSE = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee25(ids) {
2083
2344
  var t0, productList, list, errorMessage;
2084
- return _regeneratorRuntime().wrap(function _callee21$(_context21) {
2085
- while (1) switch (_context21.prev = _context21.next) {
2345
+ return _regeneratorRuntime().wrap(function _callee25$(_context25) {
2346
+ while (1) switch (_context25.prev = _context25.next) {
2086
2347
  case 0:
2087
2348
  if (this.productDataSource) {
2088
- _context21.next = 3;
2349
+ _context25.next = 3;
2089
2350
  break;
2090
2351
  }
2091
2352
  this.logWarning('fetchProductsBySSE: ProductDataSource 不可用');
2092
- return _context21.abrupt("return", []);
2353
+ return _context25.abrupt("return", []);
2093
2354
  case 3:
2094
2355
  this.logInfo('fetchProductsBySSE: 开始', {
2095
2356
  ids: ids,
2096
2357
  count: ids.length
2097
2358
  });
2098
2359
  t0 = performance.now();
2099
- _context21.prev = 5;
2100
- _context21.next = 8;
2360
+ _context25.prev = 5;
2361
+ _context25.next = 8;
2101
2362
  return this.productDataSource.run({
2102
2363
  sse: {
2103
2364
  query: {
@@ -2107,7 +2368,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
2107
2368
  }
2108
2369
  });
2109
2370
  case 8:
2110
- productList = _context21.sent;
2371
+ productList = _context25.sent;
2111
2372
  list = productList || [];
2112
2373
  perfMark('fetchProductsBySSE', performance.now() - t0, {
2113
2374
  count: list.length
@@ -2117,23 +2378,23 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
2117
2378
  receivedCount: list.length,
2118
2379
  duration: "".concat(Math.round(performance.now() - t0), "ms")
2119
2380
  });
2120
- return _context21.abrupt("return", list);
2381
+ return _context25.abrupt("return", list);
2121
2382
  case 15:
2122
- _context21.prev = 15;
2123
- _context21.t0 = _context21["catch"](5);
2124
- errorMessage = _context21.t0 instanceof Error ? _context21.t0.message : String(_context21.t0);
2383
+ _context25.prev = 15;
2384
+ _context25.t0 = _context25["catch"](5);
2385
+ errorMessage = _context25.t0 instanceof Error ? _context25.t0.message : String(_context25.t0);
2125
2386
  this.logError('fetchProductsBySSE: 失败', {
2126
2387
  ids: ids,
2127
2388
  error: errorMessage
2128
2389
  });
2129
- return _context21.abrupt("return", []);
2390
+ return _context25.abrupt("return", []);
2130
2391
  case 20:
2131
2392
  case "end":
2132
- return _context21.stop();
2393
+ return _context25.stop();
2133
2394
  }
2134
- }, _callee21, this, [[5, 15]]);
2395
+ }, _callee25, this, [[5, 15]]);
2135
2396
  }));
2136
- function fetchProductsBySSE(_x20) {
2397
+ function fetchProductsBySSE(_x24) {
2137
2398
  return _fetchProductsBySSE.apply(this, arguments);
2138
2399
  }
2139
2400
  return fetchProductsBySSE;
@@ -2141,63 +2402,84 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
2141
2402
  /**
2142
2403
  * 将 body 完整数据直接覆盖到本地 store(不调用报价单接口)
2143
2404
  * 已存在的 → 直接替换;不存在的 → 追加
2144
- * 同时更新 Map 缓存、IndexDB,触发 onProductsChanged
2145
- * 价格缓存由 processProductSyncMessages 末尾统一清除
2405
+ *
2406
+ * @example
2407
+ * await this.applyBodyUpdatesToStore(bodyUpdates, { skipIndexDB: true })
2146
2408
  */
2147
2409
  )
2148
2410
  }, {
2149
2411
  key: "applyBodyUpdatesToStore",
2150
2412
  value: (function () {
2151
- var _applyBodyUpdatesToStore = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee22(bodyUpdates) {
2152
- var updatedCount, newCount, appliedIds, _iterator11, _step11, _step11$value, id, body;
2153
- return _regeneratorRuntime().wrap(function _callee22$(_context22) {
2154
- while (1) switch (_context22.prev = _context22.next) {
2413
+ var _applyBodyUpdatesToStore = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee26(bodyUpdates, options) {
2414
+ var changedProductIds, updatedCount, newCount, appliedIds, mergeActions, changedProducts, _iterator15, _step15, _step15$value, id, body;
2415
+ return _regeneratorRuntime().wrap(function _callee26$(_context26) {
2416
+ while (1) switch (_context26.prev = _context26.next) {
2155
2417
  case 0:
2418
+ changedProductIds = _toConsumableArray(bodyUpdates.keys());
2156
2419
  this.logInfo('applyBodyUpdatesToStore: 开始', {
2157
2420
  count: bodyUpdates.size
2158
2421
  });
2159
2422
  updatedCount = 0;
2160
2423
  newCount = 0;
2161
2424
  appliedIds = new Set();
2425
+ mergeActions = {};
2426
+ changedProducts = [];
2162
2427
  this.store.list = this.store.list.map(function (p) {
2163
2428
  if (bodyUpdates.has(p.id)) {
2164
2429
  updatedCount++;
2165
2430
  appliedIds.add(p.id);
2166
- return bodyUpdates.get(p.id);
2431
+ mergeActions[p.id] = 'update';
2432
+ var next = bodyUpdates.get(p.id);
2433
+ changedProducts.push(next);
2434
+ return next;
2167
2435
  }
2168
2436
  return p;
2169
2437
  });
2170
- _iterator11 = _createForOfIteratorHelper(bodyUpdates);
2438
+ _iterator15 = _createForOfIteratorHelper(bodyUpdates);
2171
2439
  try {
2172
- for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
2173
- _step11$value = _slicedToArray(_step11.value, 2), id = _step11$value[0], body = _step11$value[1];
2440
+ for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
2441
+ _step15$value = _slicedToArray(_step15.value, 2), id = _step15$value[0], body = _step15$value[1];
2174
2442
  if (!appliedIds.has(id)) {
2175
2443
  this.store.list.push(body);
2176
2444
  newCount++;
2445
+ mergeActions[id] = 'insert';
2446
+ changedProducts.push(body);
2177
2447
  }
2178
2448
  }
2179
2449
  } catch (err) {
2180
- _iterator11.e(err);
2450
+ _iterator15.e(err);
2181
2451
  } finally {
2182
- _iterator11.f();
2452
+ _iterator15.f();
2183
2453
  }
2184
2454
  this.syncProductsMap();
2185
- _context22.next = 10;
2186
- return this.saveProductsToIndexDB(this.store.list);
2187
- case 10:
2188
- this.core.effects.emit(ProductsHooks.onProductsChanged, this.store.list);
2455
+ if (options !== null && options !== void 0 && options.skipIndexDB) {
2456
+ _context26.next = 14;
2457
+ break;
2458
+ }
2459
+ _context26.next = 14;
2460
+ return this.patchProductsInIndexDB(changedProducts, 'pubsub.bodyUpdate', mergeActions);
2461
+ case 14:
2462
+ if (!(options !== null && options !== void 0 && options.skipEmit)) {
2463
+ this.core.effects.emit(ProductsHooks.onProductsChanged, this.store.list);
2464
+ }
2189
2465
  this.logInfo('applyBodyUpdatesToStore: 完成', {
2190
2466
  updatedCount: updatedCount,
2191
2467
  newCount: newCount,
2192
2468
  totalCount: this.store.list.length
2193
2469
  });
2194
- case 12:
2470
+ return _context26.abrupt("return", {
2471
+ changedProducts: changedProducts,
2472
+ mergeActions: mergeActions,
2473
+ updatedCount: updatedCount,
2474
+ newCount: newCount
2475
+ });
2476
+ case 17:
2195
2477
  case "end":
2196
- return _context22.stop();
2478
+ return _context26.stop();
2197
2479
  }
2198
- }, _callee22, this);
2480
+ }, _callee26, this);
2199
2481
  }));
2200
- function applyBodyUpdatesToStore(_x21) {
2482
+ function applyBodyUpdatesToStore(_x25, _x26) {
2201
2483
  return _applyBodyUpdatesToStore.apply(this, arguments);
2202
2484
  }
2203
2485
  return applyBodyUpdatesToStore;
@@ -2205,68 +2487,91 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
2205
2487
  /**
2206
2488
  * 将增量拉取的商品合并到 store
2207
2489
  * 已存在的 → 替换;新的 → 追加
2208
- * 同时更新 store.map、IndexDB,触发 onProductsChanged
2490
+ *
2491
+ * @example
2492
+ * await this.mergeProductsToStore(freshProducts, { skipIndexDB: true })
2209
2493
  */
2210
2494
  )
2211
2495
  }, {
2212
2496
  key: "mergeProductsToStore",
2213
2497
  value: (function () {
2214
- var _mergeProductsToStore = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee23(freshProducts) {
2215
- var freshMap, _iterator12, _step12, p, updatedList, newCount, _iterator13, _step13, _p2, updatedCount;
2216
- return _regeneratorRuntime().wrap(function _callee23$(_context23) {
2217
- while (1) switch (_context23.prev = _context23.next) {
2498
+ var _mergeProductsToStore = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee27(freshProducts, options) {
2499
+ var freshMap, _iterator16, _step16, p, mergeActions, changedProducts, updatedList, newCount, _iterator17, _step17, _p2, updatedCount, changedProductIds;
2500
+ return _regeneratorRuntime().wrap(function _callee27$(_context27) {
2501
+ while (1) switch (_context27.prev = _context27.next) {
2218
2502
  case 0:
2219
2503
  freshMap = new Map();
2220
- _iterator12 = _createForOfIteratorHelper(freshProducts);
2504
+ _iterator16 = _createForOfIteratorHelper(freshProducts);
2221
2505
  try {
2222
- for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
2223
- p = _step12.value;
2506
+ for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
2507
+ p = _step16.value;
2224
2508
  freshMap.set(p.id, p);
2225
2509
  }
2226
2510
  } catch (err) {
2227
- _iterator12.e(err);
2511
+ _iterator16.e(err);
2228
2512
  } finally {
2229
- _iterator12.f();
2513
+ _iterator16.f();
2230
2514
  }
2515
+ mergeActions = {};
2516
+ changedProducts = [];
2231
2517
  updatedList = this.store.list.map(function (p) {
2232
2518
  if (freshMap.has(p.id)) {
2233
2519
  var fresh = freshMap.get(p.id);
2234
2520
  freshMap.delete(p.id);
2521
+ mergeActions[p.id] = 'update';
2522
+ changedProducts.push(fresh);
2235
2523
  return fresh;
2236
2524
  }
2237
2525
  return p;
2238
2526
  }); // freshMap 中剩余的是新商品(create 场景)
2239
2527
  newCount = freshMap.size;
2240
- _iterator13 = _createForOfIteratorHelper(freshMap.values());
2528
+ _iterator17 = _createForOfIteratorHelper(freshMap.values());
2241
2529
  try {
2242
- for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
2243
- _p2 = _step13.value;
2530
+ for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {
2531
+ _p2 = _step17.value;
2244
2532
  updatedList.push(_p2);
2533
+ mergeActions[_p2.id] = 'insert';
2534
+ changedProducts.push(_p2);
2245
2535
  }
2246
2536
  } catch (err) {
2247
- _iterator13.e(err);
2537
+ _iterator17.e(err);
2248
2538
  } finally {
2249
- _iterator13.f();
2539
+ _iterator17.f();
2250
2540
  }
2251
2541
  updatedCount = freshProducts.length - newCount;
2542
+ changedProductIds = freshProducts.map(function (p) {
2543
+ return p.id;
2544
+ });
2252
2545
  this.store.list = updatedList;
2253
2546
  this.syncProductsMap();
2254
- _context23.next = 12;
2255
- return this.saveProductsToIndexDB(this.store.list);
2256
- case 12:
2547
+ if (options !== null && options !== void 0 && options.skipIndexDB) {
2548
+ _context27.next = 16;
2549
+ break;
2550
+ }
2551
+ _context27.next = 16;
2552
+ return this.patchProductsInIndexDB(changedProducts, 'pubsub.mergeProductsToStore', mergeActions);
2553
+ case 16:
2554
+ if (!(options !== null && options !== void 0 && options.skipEmit)) {
2555
+ this.core.effects.emit(ProductsHooks.onProductsChanged, this.store.list);
2556
+ }
2257
2557
  this.logInfo('mergeProductsToStore: 合并完成', {
2258
2558
  updatedCount: updatedCount,
2259
2559
  newCount: newCount,
2260
2560
  totalCount: this.store.list.length
2261
2561
  });
2262
- this.core.effects.emit(ProductsHooks.onProductsChanged, this.store.list);
2263
- case 14:
2562
+ return _context27.abrupt("return", {
2563
+ changedProducts: changedProducts,
2564
+ mergeActions: mergeActions,
2565
+ updatedCount: updatedCount,
2566
+ newCount: newCount
2567
+ });
2568
+ case 19:
2264
2569
  case "end":
2265
- return _context23.stop();
2570
+ return _context27.stop();
2266
2571
  }
2267
- }, _callee23, this);
2572
+ }, _callee27, this);
2268
2573
  }));
2269
- function mergeProductsToStore(_x22) {
2574
+ function mergeProductsToStore(_x27, _x28) {
2270
2575
  return _mergeProductsToStore.apply(this, arguments);
2271
2576
  }
2272
2577
  return mergeProductsToStore;
@@ -2280,56 +2585,65 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
2280
2585
  }, {
2281
2586
  key: "silentRefresh",
2282
2587
  value: (function () {
2283
- var _silentRefresh = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee24() {
2284
- var t0, products, errorMessage;
2285
- return _regeneratorRuntime().wrap(function _callee24$(_context24) {
2286
- while (1) switch (_context24.prev = _context24.next) {
2588
+ var _silentRefresh = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee28() {
2589
+ var t0, now, elapsedSincePreload, elapsedSinceFullFetch, products, errorMessage;
2590
+ return _regeneratorRuntime().wrap(function _callee28$(_context28) {
2591
+ while (1) switch (_context28.prev = _context28.next) {
2287
2592
  case 0:
2288
2593
  t0 = performance.now();
2594
+ now = Date.now();
2595
+ elapsedSincePreload = now - this.lastPreloadCompletedAtMs;
2596
+ elapsedSinceFullFetch = now - this.lastServerFullFetchAtMs;
2597
+ if (!(this.lastPreloadCompletedAtMs > 0 && elapsedSincePreload < PRODUCT_SILENT_REFRESH_MIN_INTERVAL_MS || this.lastServerFullFetchAtMs > 0 && elapsedSinceFullFetch < PRODUCT_SILENT_REFRESH_MIN_INTERVAL_MS)) {
2598
+ _context28.next = 6;
2599
+ break;
2600
+ }
2601
+ return _context28.abrupt("return", this.store.list);
2602
+ case 6:
2289
2603
  this.logInfo('silentRefresh 开始');
2290
- _context24.prev = 2;
2291
- _context24.next = 5;
2604
+ _context28.prev = 7;
2605
+ _context28.next = 10;
2292
2606
  return this.loadProductsByServer();
2293
- case 5:
2294
- products = _context24.sent;
2607
+ case 10:
2608
+ products = _context28.sent;
2295
2609
  if (!(products && products.length > 0)) {
2296
- _context24.next = 16;
2610
+ _context28.next = 21;
2297
2611
  break;
2298
2612
  }
2299
2613
  this.store.list = products;
2300
2614
  this.syncProductsMap();
2301
2615
  this.clearPriceCache();
2302
2616
  this.core.effects.emit(ProductsHooks.onProductsChanged, this.store.list);
2303
- _context24.next = 13;
2617
+ _context28.next = 18;
2304
2618
  return this.core.effects.emit(ProductsHooks.onProductsSyncCompleted, null);
2305
- case 13:
2619
+ case 18:
2306
2620
  this.logInfo('silentRefresh 完成', {
2307
2621
  productCount: products.length,
2308
2622
  duration: "".concat(Math.round(performance.now() - t0), "ms")
2309
2623
  });
2310
- _context24.next = 17;
2624
+ _context28.next = 22;
2311
2625
  break;
2312
- case 16:
2626
+ case 21:
2313
2627
  this.logWarning('silentRefresh: 服务器未返回数据');
2314
- case 17:
2628
+ case 22:
2315
2629
  perfMark('silentRefresh', performance.now() - t0, {
2316
2630
  count: this.store.list.length
2317
2631
  });
2318
- return _context24.abrupt("return", this.store.list);
2319
- case 21:
2320
- _context24.prev = 21;
2321
- _context24.t0 = _context24["catch"](2);
2322
- errorMessage = _context24.t0 instanceof Error ? _context24.t0.message : String(_context24.t0);
2632
+ return _context28.abrupt("return", this.store.list);
2633
+ case 26:
2634
+ _context28.prev = 26;
2635
+ _context28.t0 = _context28["catch"](7);
2636
+ errorMessage = _context28.t0 instanceof Error ? _context28.t0.message : String(_context28.t0);
2323
2637
  this.logError('silentRefresh 失败', {
2324
2638
  duration: "".concat(Math.round(performance.now() - t0), "ms"),
2325
2639
  error: errorMessage
2326
2640
  });
2327
- return _context24.abrupt("return", this.store.list);
2328
- case 26:
2641
+ return _context28.abrupt("return", this.store.list);
2642
+ case 31:
2329
2643
  case "end":
2330
- return _context24.stop();
2644
+ return _context28.stop();
2331
2645
  }
2332
- }, _callee24, this, [[2, 21]]);
2646
+ }, _callee28, this, [[7, 26]]);
2333
2647
  }));
2334
2648
  function silentRefresh() {
2335
2649
  return _silentRefresh.apply(this, arguments);