package com.ard.agent.tool; import com.alibaba.fastjson2.JSON; import com.ard.common.core.constant.SecurityConstants; import com.ard.common.core.domain.R; import com.ard.common.redis.service.RedisService; import com.ard.system.api.RemoteDictService; import com.ard.system.api.domain.SysDictData; import com.ard.work.api.RemoteCameraService; import com.ard.work.api.domian.ArdCamera; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.ai.tool.annotation.Tool; import org.springframework.ai.tool.annotation.ToolParam; import org.springframework.stereotype.Component; import java.util.List; import java.util.Objects; @Slf4j @Component public class MonitorTools { @Resource private RemoteCameraService remoteCameraService; @Resource private RemoteDictService remoteDictService; @Resource private RedisService redisService; // 若依的RedisCache // 字典缓存Key前缀(若依默认) private static final String DICT_KEY_PREFIX = "sys_dict:"; /** * 获取厂商名称(带Redis缓存) */ private String getFactoryName(String factoryCode) { return getDictLabel("factory", factoryCode); } /** * 获取相机类型名称(带Redis缓存) */ private String getCameraTypeName(String typeCode) { return getDictLabel("camera_type", typeCode); } /** * 获取字典标签(直接从Redis缓存读取) */ private String getDictLabel(String dictType, String dictValue) { if (dictValue == null || dictValue.isEmpty()) { return "未知"; } // 若依框架:从缓存获取字典数据 List dictDatas = redisService.getCacheObject("sys_dict:" + dictType); if (dictDatas == null || dictDatas.isEmpty()) { // 如果缓存为空,可以从远程服务加载一次 R> result = remoteDictService.dictTypeRpc(dictType, SecurityConstants.INNER); if (result != null && result.getCode() == R.SUCCESS) { dictDatas = result.getData(); // 重新放入缓存 redisService.setCacheObject("sys_dict:" + dictType, dictDatas); } } if (dictDatas != null) { return dictDatas.stream() .filter(dict -> dictValue.equals(dict.getDictValue())) .map(SysDictData::getDictLabel) .findFirst() .orElse("未知(" + dictValue + ")"); } return "未知(" + dictValue + ")"; } @Tool(description = "获取指定摄像机的详细信息,包括IP、名称、状态等") public String getCameraDetail(@ToolParam(description = "摄像机ID,如CAM-001") String cameraId) { log.info("AI调用getCameraDetail工具,参数: cameraId={}", cameraId); if (cameraId == null || cameraId.isEmpty()) { return "错误:摄像机ID不能为空"; } try { R result = remoteCameraService.getCameraInfoRpc(cameraId, SecurityConstants.INNER); if (result == null) { return "错误:服务返回空结果"; } if (result.getCode() == R.SUCCESS) { ArdCamera camera = result.getData(); if (camera == null) { return "提示:未找到摄像机ID为 " + cameraId + " 的摄像机"; } return JSON.toJSONString(camera); } else { return String.format("获取摄像机信息失败:%s (code: %d)", result.getMsg(), result.getCode()); } } catch (Exception e) { log.error("调用getCameraInfoRpc异常", e); return "系统异常:" + e.getMessage(); } } @Tool(description = "搜索摄像机,支持名称、IP、端口、用户名、密码、坐标、状态关键词模糊查询") public String searchCameras(@ToolParam(description = "搜索关键词,支持摄像机名称或ID") String keyword) { log.info("AI调用searchCameras工具,参数: keyword={}", keyword); try { R> result = remoteCameraService.getAllCamera(SecurityConstants.INNER); if (result == null) { return "错误:服务返回空结果"; } if (result.getCode() != R.SUCCESS) { return String.format("获取摄像机列表失败:%s", result.getMsg()); } List cameras = result.getData(); if (cameras == null || cameras.isEmpty()) { return "未找到任何摄像机"; } List filteredCameras = cameras; if (filteredCameras.isEmpty()) { return "未找到符合条件的摄像机"; } StringBuilder resultStr = new StringBuilder(); resultStr.append(String.format("找到%d台摄像机:\n", filteredCameras.size())); for (ArdCamera camera : filteredCameras) { resultStr.append(String.format(" - ID: %s, 名称: %s, IP: %s, 厂商: %s,状态: %s, 类型: %s\n", camera.getId(), camera.getName(), camera.getIp(), getFactoryName(camera.getFactory()), Objects.equals(camera.getState(), "1") ? "在线" : "离线", getCameraTypeName(camera.getType()) )); } return resultStr.toString(); } catch (Exception e) { log.error("调用getAllCamera异常", e); return "系统异常:" + e.getMessage(); } } @Tool(description = """ 修改摄像机信息。传入摄像机ID和需要修改的字段,不传的字段保持原值不变。 使用示例: - "把CAM-001的名字改成大门摄像头" → 传入 {id:"CAM-001", name:"大门摄像头"} - "将CAM-002设置为离线" → 传入 {id:"CAM-002", state:"0"} 注意:id为必填项。 """) public String updateCameraInfo( @ToolParam(description = "摄像机对象,包含id和需要修改的字段") ArdCamera updateParams) { log.info("AI调用updateCameraInfo工具,参数: {}", updateParams); // 必填校验 if (updateParams == null || updateParams.getId() == null || updateParams.getId().isEmpty()) { return "错误:摄像机ID不能为空"; } String cameraId = updateParams.getId(); try { // 3. 直接调用 Feign 接口 R updateResult = remoteCameraService.updateCamera(updateParams, SecurityConstants.INNER); if (updateResult == null || updateResult.getCode() != R.SUCCESS) { return "修改失败:" + (updateResult != null ? updateResult.getMsg() : "服务返回空"); } // 4. 返回最新信息 R newResult = remoteCameraService.getCameraInfoRpc(cameraId, SecurityConstants.INNER); ArdCamera newCamera = newResult.getData(); return String.format("✅ 摄像机信息修改成功!\n\n" + "| 字段 | 修改后的值 |\n" + "|------|-----------|\n" + "| ID | %s |\n" + "| 名称 | %s |\n" + "| IP | %s |\n" + "| 位置 | %s, %s |\n" + "| 状态 | %s |\n" + "| 类型 | %s |\n" + "| 厂家 | %s |", newCamera.getId(), newCamera.getName(), newCamera.getIp(), newCamera.getLongitude(), newCamera.getLatitude(), "1".equals(newCamera.getState()) ? "在线" : "离线", getCameraTypeName(newCamera.getType()), getFactoryName(newCamera.getFactory())); } catch (Exception e) { log.error("调用updateCamera异常", e); return "系统异常:" + e.getMessage(); } } }