|
@@ -325,7 +325,7 @@ public class AiSmartCleanService {
|
|
|
// 判定开始即推一次快照:前端据此建立初始进度(此后全靠 SSE 推送,不再轮询)
|
|
// 判定开始即推一次快照:前端据此建立初始进度(此后全靠 SSE 推送,不再轮询)
|
|
|
pushProgress(caseId, batchId);
|
|
pushProgress(caseId, batchId);
|
|
|
// 判定并发:闸门 + 虚拟线程,结果按批次聚合。
|
|
// 判定并发:闸门 + 虚拟线程,结果按批次聚合。
|
|
|
- // ★ 判定任务跑在独立虚拟线程上,ScopedValue 绑定不会跨线程传播,
|
|
|
|
|
|
|
+ // 判定任务跑在独立虚拟线程上,ScopedValue 绑定不会跨线程传播,
|
|
|
// 必须用 runWith 显式带上案件上下文,否则 judge 里的 slave 查询
|
|
// 必须用 runWith 显式带上案件上下文,否则 judge 里的 slave 查询
|
|
|
// 会因路由不到案件库抛「请先打开案件后再操作数据」,整批判定全灭。
|
|
// 会因路由不到案件库抛「请先打开案件后再操作数据」,整批判定全灭。
|
|
|
Semaphore gate = new Semaphore(Math.max(1, maxConcurrent), true);
|
|
Semaphore gate = new Semaphore(Math.max(1, maxConcurrent), true);
|
|
@@ -374,7 +374,7 @@ public class AiSmartCleanService {
|
|
|
// 判定全部归零之后才能进清洗阶段,否则会漏掉 AI 命中的表
|
|
// 判定全部归零之后才能进清洗阶段,否则会漏掉 AI 命中的表
|
|
|
stage(batchId, AiCleanStageEnum.CLEANING_EXISTING);
|
|
stage(batchId, AiCleanStageEnum.CLEANING_EXISTING);
|
|
|
pushProgress(caseId, batchId);
|
|
pushProgress(caseId, batchId);
|
|
|
- // ★ 按降级顺序串行清洗(需求 2026-10-11):1级(上传已匹配模板)先洗并等它
|
|
|
|
|
|
|
+ // 按降级顺序串行清洗(需求 2026-10-11):1级(上传已匹配模板)先洗并等它
|
|
|
// 全部落库,再洗 2级(AI 命中既有模板),然后才进 3级(AI 自建表入库)。
|
|
// 全部落库,再洗 2级(AI 命中既有模板),然后才进 3级(AI 自建表入库)。
|
|
|
// 4级(无法清洗)在判定阶段就只标记、不产生清洗任务。
|
|
// 4级(无法清洗)在判定阶段就只标记、不产生清洗任务。
|
|
|
int toExisting = dispatchExistingByLevel(roots, existingHits);
|
|
int toExisting = dispatchExistingByLevel(roots, existingHits);
|