@pisell/pisellos 2.2.88 → 2.2.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/model/strategy/adapter/promotion/index.js +9 -0
- package/dist/server/index.d.ts +5 -0
- package/dist/server/index.js +22 -9
- package/dist/server/modules/products/index.d.ts +16 -11
- package/dist/server/modules/products/index.js +412 -308
- package/lib/server/index.d.ts +5 -0
- package/lib/server/index.js +20 -7
- package/lib/server/modules/products/index.d.ts +16 -11
- package/lib/server/modules/products/index.js +139 -45
- package/package.json +1 -1
package/lib/server/index.d.ts
CHANGED
|
@@ -154,11 +154,16 @@ declare class Server {
|
|
|
154
154
|
/**
|
|
155
155
|
* 商品查询的核心计算逻辑(编排 Products、Menu、Schedule 模块)
|
|
156
156
|
* 供 handleProductQuery 首次返回及 pubsub 变更推送复用
|
|
157
|
+
* @param context 查询上下文
|
|
158
|
+
* @param options 可选参数
|
|
159
|
+
* @param options.changedIds 变更的商品 IDs,用于增量更新价格缓存
|
|
157
160
|
*/
|
|
158
161
|
private computeProductQueryResult;
|
|
159
162
|
/**
|
|
160
163
|
* 数据变更后,遍历所有订阅者重新计算查询结果并通过 callback 推送
|
|
161
164
|
* 由 ProductsModule 的 onProductsSyncCompleted 事件触发
|
|
165
|
+
* @param options 可选参数
|
|
166
|
+
* @param options.changedIds 变更的商品 IDs,用于增量更新价格缓存
|
|
162
167
|
*/
|
|
163
168
|
private recomputeAndNotifyProductQuery;
|
|
164
169
|
/**
|
package/lib/server/index.js
CHANGED
|
@@ -415,8 +415,10 @@ var Server = class {
|
|
|
415
415
|
} else {
|
|
416
416
|
this.logInfo("跳过自动预加载", { autoPreload });
|
|
417
417
|
}
|
|
418
|
-
this.core.effects.on(import_types.ProductsHooks.onProductsSyncCompleted, () => {
|
|
419
|
-
this.recomputeAndNotifyProductQuery(
|
|
418
|
+
this.core.effects.on(import_types.ProductsHooks.onProductsSyncCompleted, (payload) => {
|
|
419
|
+
this.recomputeAndNotifyProductQuery({
|
|
420
|
+
changedIds: payload == null ? void 0 : payload.changedIds
|
|
421
|
+
});
|
|
420
422
|
});
|
|
421
423
|
const duration = Date.now() - startTime;
|
|
422
424
|
this.logInfo("Server 初始化完成", {
|
|
@@ -654,14 +656,18 @@ var Server = class {
|
|
|
654
656
|
/**
|
|
655
657
|
* 商品查询的核心计算逻辑(编排 Products、Menu、Schedule 模块)
|
|
656
658
|
* 供 handleProductQuery 首次返回及 pubsub 变更推送复用
|
|
659
|
+
* @param context 查询上下文
|
|
660
|
+
* @param options 可选参数
|
|
661
|
+
* @param options.changedIds 变更的商品 IDs,用于增量更新价格缓存
|
|
657
662
|
*/
|
|
658
|
-
async computeProductQueryResult(context) {
|
|
663
|
+
async computeProductQueryResult(context, options) {
|
|
659
664
|
const tTotal = performance.now();
|
|
660
665
|
const { menu_list_ids, schedule_date, schedule_datetime } = context;
|
|
661
666
|
this.logInfo("computeProductQueryResult 开始", {
|
|
662
667
|
menuListIdsCount: (menu_list_ids == null ? void 0 : menu_list_ids.length) ?? 0,
|
|
663
668
|
schedule_datetime,
|
|
664
|
-
schedule_date
|
|
669
|
+
schedule_date,
|
|
670
|
+
changedIds: options == null ? void 0 : options.changedIds
|
|
665
671
|
});
|
|
666
672
|
if (!this.products) {
|
|
667
673
|
this.logError("computeProductQueryResult: Products 模块未注册");
|
|
@@ -691,6 +697,8 @@ var Server = class {
|
|
|
691
697
|
const tPrice = performance.now();
|
|
692
698
|
const allProductsWithPrice = await this.products.getProductsWithPrice(schedule_date, {
|
|
693
699
|
scheduleModule: this.getSchedule()
|
|
700
|
+
}, {
|
|
701
|
+
changedIds: options == null ? void 0 : options.changedIds
|
|
694
702
|
});
|
|
695
703
|
(0, import_product.perfMark)("computeQuery.getProductsWithPrice", performance.now() - tPrice, {
|
|
696
704
|
count: allProductsWithPrice.length
|
|
@@ -736,16 +744,21 @@ var Server = class {
|
|
|
736
744
|
/**
|
|
737
745
|
* 数据变更后,遍历所有订阅者重新计算查询结果并通过 callback 推送
|
|
738
746
|
* 由 ProductsModule 的 onProductsSyncCompleted 事件触发
|
|
747
|
+
* @param options 可选参数
|
|
748
|
+
* @param options.changedIds 变更的商品 IDs,用于增量更新价格缓存
|
|
739
749
|
*/
|
|
740
|
-
async recomputeAndNotifyProductQuery() {
|
|
750
|
+
async recomputeAndNotifyProductQuery(options) {
|
|
741
751
|
if (this.productQuerySubscribers.size === 0)
|
|
742
752
|
return;
|
|
743
753
|
this.logInfo("recomputeAndNotifyProductQuery: 开始推送", {
|
|
744
|
-
subscriberCount: this.productQuerySubscribers.size
|
|
754
|
+
subscriberCount: this.productQuerySubscribers.size,
|
|
755
|
+
changedIds: options == null ? void 0 : options.changedIds
|
|
745
756
|
});
|
|
746
757
|
for (const [subscriberId, subscriber] of this.productQuerySubscribers.entries()) {
|
|
747
758
|
try {
|
|
748
|
-
const result = await this.computeProductQueryResult(subscriber.context
|
|
759
|
+
const result = await this.computeProductQueryResult(subscriber.context, {
|
|
760
|
+
changedIds: options == null ? void 0 : options.changedIds
|
|
761
|
+
});
|
|
749
762
|
subscriber.callback(result);
|
|
750
763
|
this.logInfo("recomputeAndNotifyProductQuery: 已推送", { subscriberId });
|
|
751
764
|
} catch (error) {
|
|
@@ -53,14 +53,20 @@ export declare class ProductsModule extends BaseModule implements Module {
|
|
|
53
53
|
* 缓存的是已经应用了价格的完整商品列表,避免重复转换
|
|
54
54
|
* @param schedule_date 日期
|
|
55
55
|
* @param extraContext 额外的上下文数据(可选,由 Server 层传入)
|
|
56
|
+
* @param options 可选参数
|
|
57
|
+
* @param options.changedIds 变更的商品 IDs,非空时仅对这些商品增量执行 prepare 并更新缓存
|
|
56
58
|
* @returns 应用了价格的商品列表
|
|
57
59
|
*/
|
|
58
|
-
getProductsWithPrice(schedule_date: string, extraContext?: Partial<ProductFormatterContext
|
|
60
|
+
getProductsWithPrice(schedule_date: string, extraContext?: Partial<ProductFormatterContext>, options?: {
|
|
61
|
+
changedIds?: number[];
|
|
62
|
+
}): Promise<ProductData[]>;
|
|
59
63
|
/**
|
|
60
64
|
* 准备带价格的商品数据(通过格式化器流程处理)
|
|
61
65
|
* @param schedule_date 日期
|
|
62
66
|
* @param extraContext 额外的上下文数据(可选)
|
|
63
|
-
* @
|
|
67
|
+
* @param options 可选参数
|
|
68
|
+
* @param options.productIds 指定商品 IDs,仅处理这些商品;不传则处理全量
|
|
69
|
+
* @returns 处理后的商品列表
|
|
64
70
|
* @private
|
|
65
71
|
*/
|
|
66
72
|
private prepareProductsWithPrice;
|
|
@@ -156,11 +162,6 @@ export declare class ProductsModule extends BaseModule implements Module {
|
|
|
156
162
|
* 用于 pubsub 同步 create / update / batch_update 场景
|
|
157
163
|
*/
|
|
158
164
|
refreshProducts(): Promise<ProductData[]>;
|
|
159
|
-
/**
|
|
160
|
-
* 指定商品的报价单价格变更时,清除价格缓存
|
|
161
|
-
* 后续查询会走完整的 formatter 管道重建缓存
|
|
162
|
-
*/
|
|
163
|
-
updateProductPriceByIds(ids: number[]): Promise<void>;
|
|
164
165
|
/**
|
|
165
166
|
* 清空缓存
|
|
166
167
|
*/
|
|
@@ -202,14 +203,18 @@ export declare class ProductsModule extends BaseModule implements Module {
|
|
|
202
203
|
*
|
|
203
204
|
* product 模块:
|
|
204
205
|
* - operation === 'delete' → 本地删除
|
|
205
|
-
* - change_types 包含 price →
|
|
206
|
+
* - change_types 包含 price → 仅收集变更 IDs(不拉商品数据)
|
|
206
207
|
* - 有 body → body 完整数据直接覆盖本地
|
|
208
|
+
* - 其他 → SSE 增量拉取
|
|
207
209
|
*
|
|
208
|
-
* product_collection / product_category
|
|
210
|
+
* product_collection / product_category:
|
|
209
211
|
* - 按 relation_product_ids SSE 拉取受影响商品
|
|
210
212
|
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
+
* product_quotation:
|
|
214
|
+
* - 报价单变更影响范围大,直接清除价格缓存走全量重建
|
|
215
|
+
*
|
|
216
|
+
* 处理完成后 emit onProductsSyncCompleted(携带 changedIds),
|
|
217
|
+
* Server 层监听该事件后对变更商品增量执行 prepareProductsWithPrice 并更新缓存
|
|
213
218
|
*/
|
|
214
219
|
private processProductSyncMessages;
|
|
215
220
|
/**
|
|
@@ -177,7 +177,7 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
177
177
|
duration: `${duration}ms`,
|
|
178
178
|
error: errorMessage
|
|
179
179
|
});
|
|
180
|
-
|
|
180
|
+
return [];
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
/**
|
|
@@ -186,13 +186,70 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
186
186
|
* 缓存的是已经应用了价格的完整商品列表,避免重复转换
|
|
187
187
|
* @param schedule_date 日期
|
|
188
188
|
* @param extraContext 额外的上下文数据(可选,由 Server 层传入)
|
|
189
|
+
* @param options 可选参数
|
|
190
|
+
* @param options.changedIds 变更的商品 IDs,非空时仅对这些商品增量执行 prepare 并更新缓存
|
|
189
191
|
* @returns 应用了价格的商品列表
|
|
190
192
|
*/
|
|
191
|
-
async getProductsWithPrice(schedule_date, extraContext) {
|
|
193
|
+
async getProductsWithPrice(schedule_date, extraContext, options) {
|
|
192
194
|
const t0 = performance.now();
|
|
193
195
|
const cacheKey = schedule_date;
|
|
196
|
+
const changedIds = options == null ? void 0 : options.changedIds;
|
|
194
197
|
if (this.productsPriceCache.has(cacheKey)) {
|
|
195
198
|
const cachedProducts = this.productsPriceCache.get(cacheKey);
|
|
199
|
+
if (changedIds && changedIds.length > 0) {
|
|
200
|
+
this.logInfo("商品价格缓存命中,增量更新变更商品", {
|
|
201
|
+
cacheKey,
|
|
202
|
+
changedIds,
|
|
203
|
+
cachedProductCount: cachedProducts.length
|
|
204
|
+
});
|
|
205
|
+
try {
|
|
206
|
+
const updatedProducts = await this.prepareProductsWithPrice(
|
|
207
|
+
schedule_date,
|
|
208
|
+
extraContext,
|
|
209
|
+
{ productIds: changedIds }
|
|
210
|
+
);
|
|
211
|
+
if (updatedProducts.length > 0) {
|
|
212
|
+
const updatedMap = new Map(updatedProducts.map((p) => [p.id, p]));
|
|
213
|
+
const mergedCache = [];
|
|
214
|
+
for (const p of cachedProducts) {
|
|
215
|
+
if (updatedMap.has(p.id)) {
|
|
216
|
+
mergedCache.push(updatedMap.get(p.id));
|
|
217
|
+
updatedMap.delete(p.id);
|
|
218
|
+
} else {
|
|
219
|
+
mergedCache.push(p);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
for (const p of updatedMap.values()) {
|
|
223
|
+
mergedCache.push(p);
|
|
224
|
+
}
|
|
225
|
+
this.productsPriceCache.set(cacheKey, mergedCache);
|
|
226
|
+
this.logInfo("增量更新完成", {
|
|
227
|
+
cacheKey,
|
|
228
|
+
changedCount: updatedProducts.length,
|
|
229
|
+
totalCount: mergedCache.length
|
|
230
|
+
});
|
|
231
|
+
(0, import_product.perfMark)("getProductsWithPrice(incrementalUpdate)", performance.now() - t0, {
|
|
232
|
+
cacheKey,
|
|
233
|
+
changedCount: changedIds.length,
|
|
234
|
+
count: mergedCache.length
|
|
235
|
+
});
|
|
236
|
+
return mergedCache;
|
|
237
|
+
}
|
|
238
|
+
} catch (error) {
|
|
239
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
240
|
+
this.logError("增量更新失败,返回现有缓存", {
|
|
241
|
+
cacheKey,
|
|
242
|
+
changedIds,
|
|
243
|
+
error: errorMessage
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
(0, import_product.perfMark)("getProductsWithPrice(incrementalUpdate)", performance.now() - t0, {
|
|
247
|
+
cacheKey,
|
|
248
|
+
changedCount: changedIds.length,
|
|
249
|
+
count: cachedProducts.length
|
|
250
|
+
});
|
|
251
|
+
return cachedProducts;
|
|
252
|
+
}
|
|
196
253
|
(0, import_product.perfMark)("getProductsWithPrice(cacheHit)", performance.now() - t0, {
|
|
197
254
|
cacheKey,
|
|
198
255
|
count: cachedProducts.length
|
|
@@ -221,21 +278,37 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
221
278
|
* 准备带价格的商品数据(通过格式化器流程处理)
|
|
222
279
|
* @param schedule_date 日期
|
|
223
280
|
* @param extraContext 额外的上下文数据(可选)
|
|
224
|
-
* @
|
|
281
|
+
* @param options 可选参数
|
|
282
|
+
* @param options.productIds 指定商品 IDs,仅处理这些商品;不传则处理全量
|
|
283
|
+
* @returns 处理后的商品列表
|
|
225
284
|
* @private
|
|
226
285
|
*/
|
|
227
|
-
async prepareProductsWithPrice(schedule_date, extraContext) {
|
|
286
|
+
async prepareProductsWithPrice(schedule_date, extraContext, options) {
|
|
228
287
|
const tTotal = performance.now();
|
|
229
|
-
|
|
288
|
+
const targetIds = options == null ? void 0 : options.productIds;
|
|
289
|
+
const isIncremental = targetIds && targetIds.length > 0;
|
|
290
|
+
this.logInfo("prepareProductsWithPrice 开始处理", {
|
|
291
|
+
schedule_date,
|
|
292
|
+
mode: isIncremental ? "incremental" : "full",
|
|
293
|
+
targetIdsCount: targetIds == null ? void 0 : targetIds.length
|
|
294
|
+
});
|
|
230
295
|
try {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
ids
|
|
296
|
+
let products;
|
|
297
|
+
let ids;
|
|
298
|
+
if (isIncremental) {
|
|
299
|
+
const idSet = new Set(targetIds);
|
|
300
|
+
products = this.getProductsRef().filter((p) => idSet.has(p.id));
|
|
301
|
+
ids = products.map((p) => p.id);
|
|
302
|
+
} else {
|
|
303
|
+
products = this.getProductsRef();
|
|
304
|
+
const tIds = performance.now();
|
|
305
|
+
ids = new Array(products.length);
|
|
306
|
+
for (let i = 0; i < products.length; i++) {
|
|
307
|
+
ids[i] = products[i].id;
|
|
308
|
+
}
|
|
309
|
+
(0, import_product.perfMark)("prepareProducts.extractIds", performance.now() - tIds, { count: ids.length });
|
|
237
310
|
}
|
|
238
|
-
|
|
311
|
+
this.logInfo("获取到商品列表", { productCount: products.length });
|
|
239
312
|
const tPrice = performance.now();
|
|
240
313
|
const priceData = await this.loadProductsPrice({
|
|
241
314
|
ids,
|
|
@@ -249,23 +322,27 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
249
322
|
...extraContext
|
|
250
323
|
};
|
|
251
324
|
const tFormat = performance.now();
|
|
252
|
-
const processedProducts = await this.applyFormatters(
|
|
325
|
+
const processedProducts = await this.applyFormatters(products, context);
|
|
253
326
|
(0, import_product.perfMark)("prepareProducts.applyFormatters", performance.now() - tFormat, {
|
|
254
|
-
count:
|
|
327
|
+
count: products.length,
|
|
255
328
|
formatterCount: this.formatters.length
|
|
256
329
|
});
|
|
257
330
|
this.logInfo("prepareProductsWithPrice 处理完成", {
|
|
258
|
-
|
|
331
|
+
mode: isIncremental ? "incremental" : "full",
|
|
332
|
+
originalProductCount: products.length,
|
|
259
333
|
processedProductCount: processedProducts.length,
|
|
260
334
|
formatterCount: this.formatters.length
|
|
261
335
|
});
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
336
|
+
if (!isIncremental) {
|
|
337
|
+
await this.core.effects.emit(
|
|
338
|
+
import_types.ProductsHooks.onProductsPriceApplied,
|
|
339
|
+
processedProducts
|
|
340
|
+
);
|
|
341
|
+
}
|
|
266
342
|
(0, import_product.perfMark)("prepareProductsWithPrice", performance.now() - tTotal, {
|
|
267
|
-
productCount:
|
|
268
|
-
formatterCount: this.formatters.length
|
|
343
|
+
productCount: products.length,
|
|
344
|
+
formatterCount: this.formatters.length,
|
|
345
|
+
mode: isIncremental ? "incremental" : "full"
|
|
269
346
|
});
|
|
270
347
|
return processedProducts;
|
|
271
348
|
} catch (err) {
|
|
@@ -604,14 +681,6 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
604
681
|
(0, import_product.perfMark)("refreshProducts", performance.now() - tTotal, { count: this.store.list.length });
|
|
605
682
|
return this.store.list;
|
|
606
683
|
}
|
|
607
|
-
/**
|
|
608
|
-
* 指定商品的报价单价格变更时,清除价格缓存
|
|
609
|
-
* 后续查询会走完整的 formatter 管道重建缓存
|
|
610
|
-
*/
|
|
611
|
-
async updateProductPriceByIds(ids) {
|
|
612
|
-
this.logInfo("updateProductPriceByIds: 清除价格缓存", { ids });
|
|
613
|
-
this.clearPriceCache();
|
|
614
|
-
}
|
|
615
684
|
/**
|
|
616
685
|
* 清空缓存
|
|
617
686
|
*/
|
|
@@ -838,17 +907,21 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
838
907
|
*
|
|
839
908
|
* product 模块:
|
|
840
909
|
* - operation === 'delete' → 本地删除
|
|
841
|
-
* - change_types 包含 price →
|
|
910
|
+
* - change_types 包含 price → 仅收集变更 IDs(不拉商品数据)
|
|
842
911
|
* - 有 body → body 完整数据直接覆盖本地
|
|
912
|
+
* - 其他 → SSE 增量拉取
|
|
843
913
|
*
|
|
844
|
-
* product_collection / product_category
|
|
914
|
+
* product_collection / product_category:
|
|
845
915
|
* - 按 relation_product_ids SSE 拉取受影响商品
|
|
846
916
|
*
|
|
847
|
-
*
|
|
848
|
-
*
|
|
917
|
+
* product_quotation:
|
|
918
|
+
* - 报价单变更影响范围大,直接清除价格缓存走全量重建
|
|
919
|
+
*
|
|
920
|
+
* 处理完成后 emit onProductsSyncCompleted(携带 changedIds),
|
|
921
|
+
* Server 层监听该事件后对变更商品增量执行 prepareProductsWithPrice 并更新缓存
|
|
849
922
|
*/
|
|
850
923
|
async processProductSyncMessages() {
|
|
851
|
-
var _a, _b, _c, _d, _e;
|
|
924
|
+
var _a, _b, _c, _d, _e, _f;
|
|
852
925
|
const messages = [...this.pendingSyncMessages];
|
|
853
926
|
this.pendingSyncMessages = [];
|
|
854
927
|
if (messages.length === 0)
|
|
@@ -857,28 +930,30 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
857
930
|
const deleteIds = [];
|
|
858
931
|
const bodyUpdates = /* @__PURE__ */ new Map();
|
|
859
932
|
const sseRefreshIds = [];
|
|
933
|
+
const priceRefreshIds = [];
|
|
934
|
+
let shouldClearPriceCache = false;
|
|
860
935
|
for (const msg of messages) {
|
|
861
936
|
const channelKey = msg._channelKey || msg.module || "product";
|
|
862
937
|
if (channelKey === "product") {
|
|
938
|
+
if ((_a = msg.relation_product_ids) == null ? void 0 : _a.length) {
|
|
939
|
+
sseRefreshIds.push(...msg.relation_product_ids);
|
|
940
|
+
}
|
|
863
941
|
if (msg.operation === "delete" || msg.action === "delete") {
|
|
864
|
-
if ((
|
|
942
|
+
if ((_b = msg.ids) == null ? void 0 : _b.length)
|
|
865
943
|
deleteIds.push(...msg.ids);
|
|
866
944
|
else if (msg.id)
|
|
867
945
|
deleteIds.push(msg.id);
|
|
868
946
|
continue;
|
|
869
947
|
}
|
|
870
|
-
if ((
|
|
948
|
+
if ((_c = msg.change_types) == null ? void 0 : _c.includes("price")) {
|
|
871
949
|
const ids = msg.ids || (msg.id ? [msg.id] : []);
|
|
872
|
-
|
|
950
|
+
priceRefreshIds.push(...ids);
|
|
873
951
|
continue;
|
|
874
952
|
}
|
|
875
953
|
if (msg.body) {
|
|
876
954
|
const bodyId = msg.body.id || msg.id;
|
|
877
955
|
if (bodyId)
|
|
878
956
|
bodyUpdates.set(bodyId, msg.body);
|
|
879
|
-
if ((_c = msg.relation_product_ids) == null ? void 0 : _c.length) {
|
|
880
|
-
sseRefreshIds.push(...msg.relation_product_ids);
|
|
881
|
-
}
|
|
882
957
|
continue;
|
|
883
958
|
}
|
|
884
959
|
if ((_d = msg.ids) == null ? void 0 : _d.length) {
|
|
@@ -886,14 +961,20 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
886
961
|
} else if (msg.id) {
|
|
887
962
|
sseRefreshIds.push(msg.id);
|
|
888
963
|
}
|
|
889
|
-
} else if (
|
|
964
|
+
} else if (channelKey === "product_quotation") {
|
|
965
|
+
shouldClearPriceCache = true;
|
|
890
966
|
if ((_e = msg.relation_product_ids) == null ? void 0 : _e.length) {
|
|
891
967
|
sseRefreshIds.push(...msg.relation_product_ids);
|
|
892
968
|
}
|
|
969
|
+
} else if (["product_collection", "product_category"].includes(channelKey)) {
|
|
970
|
+
if ((_f = msg.relation_product_ids) == null ? void 0 : _f.length) {
|
|
971
|
+
sseRefreshIds.push(...msg.relation_product_ids);
|
|
972
|
+
}
|
|
893
973
|
}
|
|
894
974
|
}
|
|
895
975
|
const uniqueDeleteIds = [...new Set(deleteIds)];
|
|
896
976
|
const uniqueSSEIds = [...new Set(sseRefreshIds)];
|
|
977
|
+
const uniquePriceIds = [...new Set(priceRefreshIds)];
|
|
897
978
|
if (uniqueDeleteIds.length > 0) {
|
|
898
979
|
await this.removeProductsByIds(uniqueDeleteIds);
|
|
899
980
|
}
|
|
@@ -910,17 +991,30 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
910
991
|
receivedCount: freshProducts.length
|
|
911
992
|
});
|
|
912
993
|
}
|
|
994
|
+
const allChangedIds = [.../* @__PURE__ */ new Set([
|
|
995
|
+
...Array.from(bodyUpdates.keys()),
|
|
996
|
+
...uniqueSSEIds,
|
|
997
|
+
...uniquePriceIds
|
|
998
|
+
])];
|
|
913
999
|
this.logInfo("processProductSyncMessages: 处理完成", {
|
|
914
1000
|
deleteCount: uniqueDeleteIds.length,
|
|
915
1001
|
bodyUpdateCount: bodyUpdates.size,
|
|
916
|
-
sseRefreshCount: uniqueSSEIds.length
|
|
1002
|
+
sseRefreshCount: uniqueSSEIds.length,
|
|
1003
|
+
priceRefreshCount: uniquePriceIds.length,
|
|
1004
|
+
allChangedIdsCount: allChangedIds.length,
|
|
1005
|
+
shouldClearPriceCache
|
|
917
1006
|
});
|
|
918
|
-
|
|
1007
|
+
const hasChanges = uniqueDeleteIds.length > 0 || allChangedIds.length > 0 || shouldClearPriceCache;
|
|
1008
|
+
if (!hasChanges) {
|
|
919
1009
|
this.logInfo("processProductSyncMessages: 没有变更,不触发 onProductsSyncCompleted");
|
|
920
1010
|
return;
|
|
921
1011
|
}
|
|
922
|
-
|
|
923
|
-
|
|
1012
|
+
if (shouldClearPriceCache) {
|
|
1013
|
+
this.clearPriceCache();
|
|
1014
|
+
}
|
|
1015
|
+
await this.core.effects.emit(import_types.ProductsHooks.onProductsSyncCompleted, {
|
|
1016
|
+
changedIds: allChangedIds
|
|
1017
|
+
});
|
|
924
1018
|
}
|
|
925
1019
|
/**
|
|
926
1020
|
* 通过 SSE 按 ids 增量拉取商品数据
|