注册垃圾检测算法并修复ROI绑定后不推送配置

问题:
1. WVP 数据库没有 garbage 算法注册,前端无法选择
2. bindAlgo/unbindAlgo/updateAlgoParams 只写数据库,不触发配置推送到边缘端
3. bindAlgo 不校验 algo_code 是否存在

修复:
- PRESET_ALGORITHMS 添加 garbage 算法注册(参数与边缘端对齐)
- bindAlgo 添加算法存在性校验
- bindAlgo/unbindAlgo/updateAlgoParams 变更后自动推送配置到边缘端
- 新增 pushRoiConfig 辅助方法

Claude Opus 4.7
This commit is contained in:
2026-04-29 14:34:25 +08:00
parent 780650f0cc
commit f478e96d97
2 changed files with 42 additions and 1 deletions

View File

@@ -74,6 +74,10 @@ public class AiAlgorithmServiceImpl implements IAiAlgorithmService {
"非机动车违停检测", "bicycle,motorcycle", "检测禁停区域内是否有非机动车自行车、电动车违规停放。确认非机动车停留10秒后开始3分钟倒计时超时触发告警。非机动车离开60秒后自动结束告警。",
"{\"confirm_vehicle_sec\":{\"type\":\"int\",\"default\":10,\"min\":5},\"parking_countdown_sec\":{\"type\":\"int\",\"default\":180,\"min\":60},\"confirm_clear_sec\":{\"type\":\"int\",\"default\":60,\"min\":10},\"cooldown_sec\":{\"type\":\"int\",\"default\":900,\"min\":0}}"
});
PRESET_ALGORITHMS.put("garbage", new String[]{
"垃圾检测", "garbage", "检测监控区域内散落垃圾的持续存在确认60秒后触发告警垃圾清理后30秒确认自动结束告警。",
"{\"confirm_garbage_sec\":{\"type\":\"int\",\"default\":60,\"min\":10,\"max\":600},\"confirm_clear_sec\":{\"type\":\"int\",\"default\":30,\"min\":10,\"max\":300},\"cooldown_sec\":{\"type\":\"int\",\"default\":600,\"min\":0}}"
});
}
@PostConstruct

View File

@@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.aiot.dao.AiAlgorithmMapper;
import com.genersoft.iot.vmp.aiot.dao.AiRoiAlgoBindMapper;
import com.genersoft.iot.vmp.aiot.dao.AiRoiMapper;
import com.genersoft.iot.vmp.aiot.service.IAiConfigLogService;
import com.genersoft.iot.vmp.aiot.service.IAiRedisConfigService;
import com.genersoft.iot.vmp.aiot.service.IAiRoiService;
import com.genersoft.iot.vmp.streamProxy.dao.StreamProxyMapper;
import com.github.pagehelper.PageHelper;
@@ -40,6 +41,9 @@ public class AiRoiServiceImpl implements IAiRoiService {
@Autowired
private IAiConfigLogService configLogService;
@Autowired
private IAiRedisConfigService redisConfigService;
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Override
@@ -157,6 +161,11 @@ public class AiRoiServiceImpl implements IAiRoiService {
if (existing != null) {
throw new IllegalArgumentException("该ROI已绑定此算法");
}
// 校验算法是否存在
AiAlgorithm algo = algorithmMapper.queryByCode(bind.getAlgoCode());
if (algo == null) {
throw new IllegalArgumentException("算法不存在: " + bind.getAlgoCode());
}
if (ObjectUtils.isEmpty(bind.getBindId())) {
bind.setBindId(UUID.randomUUID().toString());
}
@@ -170,17 +179,25 @@ public class AiRoiServiceImpl implements IAiRoiService {
bind.setUpdateTime(now);
bindMapper.add(bind);
configLogService.addLog("BIND", bind.getBindId(), null, toJson(bind), null);
// 推送配置到 Edge绑定算法后
pushRoiConfig(bind.getRoiId());
}
@Override
@Transactional
public void unbindAlgo(String bindId) {
AiRoiAlgoBind old = bindMapper.queryByBindId(bindId);
String roiId = null;
if (old != null) {
String roiId = old.getRoiId();
roiId = old.getRoiId();
bindMapper.deleteByBindId(bindId);
configLogService.addLog("BIND", bindId, toJson(old), null, null);
}
// 推送配置到 Edge解绑算法后
if (roiId != null) {
pushRoiConfig(roiId);
}
}
@Override
@@ -200,6 +217,9 @@ public class AiRoiServiceImpl implements IAiRoiService {
bind.setUpdateTime(now);
bindMapper.updateByBindId(bind);
configLogService.addLog("BIND", bind.getBindId(), toJson(old), toJson(bind), null);
// 推送配置到 Edge参数变更后
pushRoiConfig(old.getRoiId());
}
private String toJson(Object obj) {
@@ -212,4 +232,21 @@ public class AiRoiServiceImpl implements IAiRoiService {
return obj.toString();
}
}
/**
* 推送指定 ROI 所属设备的配置到边缘端
*/
private void pushRoiConfig(String roiId) {
try {
AiRoi roi = roiMapper.queryByRoiId(roiId);
if (roi != null && roi.getDeviceId() != null && !roi.getDeviceId().isEmpty()) {
redisConfigService.writeDeviceAggregatedConfig(roi.getDeviceId(), "UPDATE");
log.info("[AiRoi] ROI配置已推送到EdgeroiId={}, deviceId={}", roiId, roi.getDeviceId());
} else {
log.warn("[AiRoi] 无法确定ROI所属设备跳过推送roiId={}", roiId);
}
} catch (Exception e) {
log.error("[AiRoi] 推送ROI配置失败roiId={}", roiId, e);
}
}
}