From b62ba1ca3744d0725b3c84fd475a8cf0c7e5f582 Mon Sep 17 00:00:00 2001 From: xiaoqu-ai Date: Wed, 21 Oct 2026 12:49:54 +0800 Subject: [PATCH] =?UTF-8?q?fix(mcp):=20scope=20=E7=BB=91=E5=AE=9A=E6=9F=A5?= =?UTF-8?q?=E6=89=BE=E5=B7=A5=E5=85=B7=E6=97=B6=E5=85=BC=E5=AE=B9=20soft?= =?UTF-8?q?=5Fdelete=20=E4=B8=BA=20NULL=20=E7=9A=84=E5=8E=86=E5=8F=B2?= =?UTF-8?q?=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象:sync 作用域绑定了 4 个工具,硬件统计/设备日均/换纸明细都通了, 但 district.paper.statistics.query 仍 PERMISSION_DENIED。 原因:工具查找用 .eq(Tool::getSoftDelete, 0),而历史记录该列可能为 NULL (建表默认 0,早期插入未显式写),于是被判"工具不存在"跳过绑定。 修复:条件改为 soft_delete = 0 OR IS NULL;新增单测覆盖 NULL 场景。 --- .../iiv/agent/mcp/ScopeToolSyncService.java | 6 +++++- .../agent/mcp/ScopeToolSyncServiceTest.java | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/ScopeToolSyncService.java b/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/ScopeToolSyncService.java index ece1aaf..2d02fb4 100644 --- a/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/ScopeToolSyncService.java +++ b/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/ScopeToolSyncService.java @@ -82,8 +82,12 @@ public class ScopeToolSyncService implements ApplicationRunner { if (toolName.isEmpty()) { continue; } + // soft_delete 在历史数据里可能是 NULL(建表默认 0 但早期插入未写), + // 只按 =0 过滤会把已注册的工具误判为"不存在"而跳过绑定 + // (2026-10-21 district.paper.statistics.query 即因此未绑上)。 Tool tool = toolMapper.selectOne(new LambdaQueryWrapper() - .eq(Tool::getName, toolName).eq(Tool::getSoftDelete, 0)); + .eq(Tool::getName, toolName) + .and(w -> w.eq(Tool::getSoftDelete, 0).or().isNull(Tool::getSoftDelete))); if (tool == null) { log.warn("scope-tool binding 跳过:工具不存在 name={}", toolName); skipped++; diff --git a/xiaoqu-agent-service/src/test/java/me/iiv/agent/mcp/ScopeToolSyncServiceTest.java b/xiaoqu-agent-service/src/test/java/me/iiv/agent/mcp/ScopeToolSyncServiceTest.java index c8c9178..466b356 100644 --- a/xiaoqu-agent-service/src/test/java/me/iiv/agent/mcp/ScopeToolSyncServiceTest.java +++ b/xiaoqu-agent-service/src/test/java/me/iiv/agent/mcp/ScopeToolSyncServiceTest.java @@ -65,6 +65,25 @@ class ScopeToolSyncServiceTest { verify(scopeToolMapper, times(1)).insert(any(ScopeTool.class)); } + @Test + void bindsToolWhoseSoftDeleteColumnIsNull() { + service.rawBindings = "sync=tool.c"; + AgentScope scope = new AgentScope(); + scope.setId(4L); + scope.setCode("sync"); + when(scopeMapper.selectOne(any())).thenReturn(scope); + Tool toolC = new Tool(); + toolC.setId(12L); + toolC.setName("tool.c"); + // softDelete 为 NULL 的历史记录也要能绑上 + when(toolMapper.selectOne(any())).thenReturn(toolC); + when(scopeToolMapper.selectCount(any())).thenReturn(0L); + + service.run(null); + + verify(scopeToolMapper, times(1)).insert(any(ScopeTool.class)); + } + @Test void skipsUnknownScopeWithoutFailing() { service.rawBindings = "nope=tool.a";