From 69fd5a1ea8c6bb5b1b29fd6064c70296892d0f99 Mon Sep 17 00:00:00 2001 From: Sakura-RanChen <1908198662@qq.com> Date: Fri, 29 May 2026 17:34:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8D=E5=BC=80=E5=90=AF=E9=80=9A=E8=AE=AF?= =?UTF-8?q?=E5=BD=95=E5=8A=9F=E8=83=BD=E6=97=B6=E4=B8=8D=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=B7=A5=E5=85=B7=20=E5=85=B3=E9=97=AD?= =?UTF-8?q?=E9=80=9A=E8=AE=AF=E5=BD=95=E5=8A=9F=E8=83=BD=E6=B8=85=E9=99=A4?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xiaozhi/common/constant/Constant.java | 5 ++ .../service/AgentPluginMappingService.java | 11 +++- .../impl/AgentPluginMappingServiceImpl.java | 7 +++ .../sys/controller/SysParamsController.java | 7 ++- .../modules/sys/service/SysParamsService.java | 15 +++++ .../service/impl/SysParamsServiceImpl.java | 62 ++++++++++++++++++- .../src/components/FunctionDialog.vue | 46 +++++++++++--- 7 files changed, 139 insertions(+), 14 deletions(-) diff --git a/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java b/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java index 81ca4ffa..61a05f70 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java +++ b/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java @@ -146,6 +146,11 @@ public interface Constant { */ String SERVER_AUTH_ENABLED = "server.auth.enabled"; + /** + * 系统功能菜单配置 + */ + String SYSTEM_WEB_MENU = "system-web.menu"; + /** * 无记忆 */ diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentPluginMappingService.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentPluginMappingService.java index 79d97d2e..9411cc80 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentPluginMappingService.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentPluginMappingService.java @@ -14,7 +14,7 @@ public interface AgentPluginMappingService extends IService /** * 根据智能体id获取插件参数 - * + * * @param agentId * @return */ @@ -22,8 +22,15 @@ public interface AgentPluginMappingService extends IService /** * 根据智能体id删除插件参数 - * + * * @param agentId */ void deleteByAgentId(String agentId); + + /** + * 根据插件ID删除所有智能体的插件映射 + * + * @param pluginId 插件ID + */ + void deleteByPluginId(String pluginId); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentPluginMappingServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentPluginMappingServiceImpl.java index 6d839d9c..a8784010 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentPluginMappingServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentPluginMappingServiceImpl.java @@ -104,4 +104,11 @@ public class AgentPluginMappingServiceImpl extends ServiceImpl updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("plugin_id", pluginId); + agentPluginMappingMapper.delete(updateWrapper); + } + } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/sys/controller/SysParamsController.java b/main/manager-api/src/main/java/xiaozhi/modules/sys/controller/SysParamsController.java index 26e6d245..49317aa4 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/sys/controller/SysParamsController.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/sys/controller/SysParamsController.java @@ -114,7 +114,12 @@ public class SysParamsController { // 校验mqtt密钥长度 validateMqttSecretLength(dto.getParamCode(), dto.getParamValue()); - sysParamsService.update(dto); + // 如果是系统功能菜单配置,使用特殊处理 + if (Constant.SYSTEM_WEB_MENU.equals(dto.getParamCode())) { + sysParamsService.updateSystemWebMenu(dto.getParamValue()); + } else { + sysParamsService.update(dto); + } configService.getConfig(false); return new Result(); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/sys/service/SysParamsService.java b/main/manager-api/src/main/java/xiaozhi/modules/sys/service/SysParamsService.java index ac67a276..70ff417d 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/sys/service/SysParamsService.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/sys/service/SysParamsService.java @@ -53,4 +53,19 @@ public interface SysParamsService extends BaseService { * 初始化服务器密钥 */ void initServerSecret(); + + /** + * 获取系统功能菜单配置 + * + * @param fromCache 是否从缓存获取 + * @return 系统功能菜单配置JSON字符串 + */ + String getSystemWebMenu(boolean fromCache); + + /** + * 更新系统功能菜单配置(自动处理功能相关的插件清理) + * + * @param configJson 新的系统功能菜单配置JSON + */ + void updateSystemWebMenu(String configJson); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/sys/service/impl/SysParamsServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/sys/service/impl/SysParamsServiceImpl.java index b22dd2b9..a83c2e68 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/sys/service/impl/SysParamsServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/sys/service/impl/SysParamsServiceImpl.java @@ -22,6 +22,7 @@ import xiaozhi.common.service.impl.BaseServiceImpl; import xiaozhi.common.utils.ConvertUtils; import xiaozhi.common.utils.JsonUtils; import xiaozhi.common.utils.SM2Utils; +import xiaozhi.modules.agent.service.AgentPluginMappingService; import xiaozhi.modules.sys.dao.SysParamsDao; import xiaozhi.modules.sys.dto.SysParamsDTO; import xiaozhi.modules.sys.entity.SysParamsEntity; @@ -35,6 +36,7 @@ import xiaozhi.modules.sys.service.SysParamsService; @Service public class SysParamsServiceImpl extends BaseServiceImpl implements SysParamsService { private final SysParamsRedis sysParamsRedis; + private final AgentPluginMappingService agentPluginMappingService; @Override public PageData page(Map params) { @@ -270,4 +272,62 @@ public class SysParamsServiceImpl extends BaseServiceImpl currentMap = null; + Map newMap = null; + + try { + if (StringUtils.isNotBlank(currentConfig)) { + currentMap = JsonUtils.parseObject(currentConfig, Map.class); + } + if (StringUtils.isNotBlank(configJson)) { + newMap = JsonUtils.parseObject(configJson, Map.class); + } + } catch (Exception e) { + throw new RenException(ErrorCode.PARAM_JSON_INVALID); + } + + // 检查addressBook功能是否被关闭 + if (currentMap != null && newMap != null) { + Map currentFeatures = (Map) currentMap.get("features"); + Map newFeatures = (Map) newMap.get("features"); + + if (currentFeatures != null && newFeatures != null) { + Object currentAddressBookObj = currentFeatures.get("addressBook"); + Object newAddressBookObj = newFeatures.get("addressBook"); + + Boolean currentEnabled = false; + Boolean newEnabled = false; + + if (currentAddressBookObj instanceof Map) { + Map currentAddressBook = (Map) currentAddressBookObj; + currentEnabled = currentAddressBook.get("enabled") != null + ? (Boolean) currentAddressBook.get("enabled") : false; + } + + if (newAddressBookObj instanceof Map) { + Map newAddressBook = (Map) newAddressBookObj; + newEnabled = newAddressBook.get("enabled") != null + ? (Boolean) newAddressBook.get("enabled") : false; + } + + // 如果之前是启用状态,现在被禁用,删除所有call_device插件 + if (Boolean.TRUE.equals(currentEnabled) && !Boolean.TRUE.equals(newEnabled)) { + agentPluginMappingService.deleteByPluginId("SYSTEM_PLUGIN_CALL_DEVICE"); + } + } + } + + // 更新配置 + updateValueByCode(Constant.SYSTEM_WEB_MENU, configJson); + } +} diff --git a/main/manager-web/src/components/FunctionDialog.vue b/main/manager-web/src/components/FunctionDialog.vue index e95cca8a..595159ca 100644 --- a/main/manager-web/src/components/FunctionDialog.vue +++ b/main/manager-web/src/components/FunctionDialog.vue @@ -209,16 +209,27 @@ export default { // 功能状态 featureStatus: { - mcpAccessPoint: false + mcpAccessPoint: false, + addressBook: false } } }, computed: { selectedList() { - return this.allFunctions.filter(f => this.selectedNames.includes(f.name)); + const list = this.allFunctions.filter(f => this.selectedNames.includes(f.name)); + // 如果通讯录功能未启用,过滤掉设备呼叫设备插件 + if (!this.featureStatus.addressBook) { + return list.filter(f => f.providerCode !== 'call_device'); + } + return list; }, unselected() { - return this.allFunctions.filter(f => !this.selectedNames.includes(f.name)); + const list = this.allFunctions.filter(f => !this.selectedNames.includes(f.name)); + // 如果通讯录功能未启用,过滤掉设备呼叫设备插件 + if (!this.featureStatus.addressBook) { + return list.filter(f => f.providerCode !== 'call_device'); + } + return list; } }, watch: { @@ -239,11 +250,23 @@ export default { } }); }, - value(v) { + async value(v) { this.dialogVisible = v; if (v) { + // 加载功能状态(需要在初始化选中态之前) + await this.loadFeatureStatus(); + // 对话框打开时,初始化选中态 this.selectedNames = this.functions.map(f => f.name); + + // 如果通讯录功能未启用,从已选列表中移除设备呼叫设备插件 + if (!this.featureStatus.addressBook) { + this.selectedNames = this.selectedNames.filter(name => { + const func = this.allFunctions.find(f => f.name === name); + return func && func.providerCode !== 'call_device'; + }); + } + // 把后端传来的 this.functions(带 params)merge 到 allFunctions 上 this.functions.forEach(saved => { const idx = this.allFunctions.findIndex(f => f.name === saved.name); @@ -255,9 +278,6 @@ export default { // 右侧默认指向第一个 this.currentFunction = this.selectedList[0] || null; - // 加载功能状态 - this.loadFeatureStatus(); - // 加载MCP数据 this.loadMcpAddress(); this.loadMcpTools(); @@ -274,10 +294,11 @@ export default { async loadFeatureStatus() { // 确保featureManager已初始化完成 await featureManager.waitForInitialization(); - + const config = featureManager.getConfig(); this.featureStatus = { - mcpAccessPoint: config.mcpAccessPoint || false + mcpAccessPoint: config.mcpAccessPoint || false, + addressBook: config.addressBook || false }; }, @@ -413,7 +434,7 @@ export default { this.tempFunctions = {}; this.hasSaved = true; - const selected = this.selectedList.map(f => { + let selected = this.selectedList.map(f => { const modified = this.modifiedFunctions[f.name]; return { id: f.id, @@ -424,6 +445,11 @@ export default { } }); + // 如果通讯录功能未启用,自动取消已选的设备呼叫设备插件 + if (!this.featureStatus.addressBook) { + selected = selected.filter(f => f.providerCode !== 'call_device'); + } + this.$emit('update-functions', selected); this.dialogVisible = false; // 通知父组件对话框已关闭且已保存