diff --git a/sql/mysql/video.sql b/sql/mysql/video.sql index 480f6ac7..3cc50e40 100644 --- a/sql/mysql/video.sql +++ b/sql/mysql/video.sql @@ -935,12 +935,30 @@ CREATE TABLE `video_ai_algo_template` ( -- ============================================================================ -- 预置算法(与 FastAPI 边缘端保持一致) +-- 幂等:已存在则更新 name/target_class/param_schema/description,保持 is_active 与用户设置 INSERT INTO `video_ai_algorithm` (`algo_code`, `algo_name`, `target_class`, `param_schema`, `description`, `is_active`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES ('leave_post', '离岗检测', 'person', - '{"confirm_on_duty_sec":{"type":"int","default":10,"min":1},"confirm_leave_sec":{"type":"int","default":30,"min":1},"leave_countdown_sec":{"type":"int","default":300,"min":0},"cooldown_sec":{"type":"int","default":600,"min":0},"working_hours":{"type":"list","default":[]}}', - '检测人员是否在岗,支持工作时间段配置', 1, 'system', NOW(), 'system', NOW(), b'0', 0), + '{"leave_countdown_sec":{"type":"int","default":300,"min":0},"working_hours":{"type":"list","default":[]}}', + '检测人员是否在岗,支持工作时间段配置。算法抽帧频率:3帧/秒(固定)', + 1, '1', NOW(), '1', NOW(), b'0', 0), ('intrusion', '周界入侵检测', 'person', - '{"cooldown_seconds":{"type":"int","default":120,"min":0},"confirm_seconds":{"type":"int","default":5,"min":1}}', - '检测人员进入指定区域', 1, 'system', NOW(), 'system', NOW(), b'0', 0); + '{"cooldown_seconds":{"type":"int","default":300,"min":0},"confirm_seconds":{"type":"int","default":5,"min":1},"confirm_intrusion_seconds":{"type":"int","default":5,"min":1},"confirm_clear_seconds":{"type":"int","default":180,"min":1}}', + '检测人员进入指定区域。算法抽帧频率:1帧/秒(固定)。持续检测到人5秒触发告警,持续无人180秒自动结束告警。消失确认期间短暂有人(<5秒)不影响倒计时。', + 1, '1', NOW(), '1', NOW(), b'0', 0), +('illegal_parking', '车辆违停检测', 'car,truck,bus,motorcycle', + '{"confirm_vehicle_sec":{"type":"int","default":15,"min":5},"parking_countdown_sec":{"type":"int","default":300,"min":60},"confirm_clear_sec":{"type":"int","default":30,"min":10},"cooldown_sec":{"type":"int","default":600,"min":0}}', + '检测禁停区域内是否有车辆违规停放。确认车辆停留15秒后开始5分钟倒计时,超时触发告警。车辆离开30秒后自动结束告警。', + 1, '1', NOW(), '1', NOW(), b'0', 0), +('vehicle_congestion', '车辆拥堵检测', 'car,truck,bus,motorcycle', + '{"count_threshold":{"type":"int","default":3,"min":1},"confirm_congestion_sec":{"type":"int","default":60,"min":10},"confirm_clear_sec":{"type":"int","default":120,"min":10},"cooldown_sec":{"type":"int","default":600,"min":0}}', + '检测区域内车辆是否拥堵。当平均车辆数达到阈值并持续60秒触发告警,车辆减少并持续120秒后自动结束告警。', + 1, '1', NOW(), '1', NOW(), b'0', 0) +ON DUPLICATE KEY UPDATE + `algo_name` = VALUES(`algo_name`), + `target_class` = VALUES(`target_class`), + `param_schema` = VALUES(`param_schema`), + `description` = VALUES(`description`), + `updater` = VALUES(`updater`), + `update_time` = NOW(); SET FOREIGN_KEY_CHECKS = 1; diff --git a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/aiot/service/impl/AiAlgorithmServiceImpl.java b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/aiot/service/impl/AiAlgorithmServiceImpl.java index 0126d45c..81c019a3 100644 --- a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/aiot/service/impl/AiAlgorithmServiceImpl.java +++ b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/aiot/service/impl/AiAlgorithmServiceImpl.java @@ -5,14 +5,12 @@ import com.viewsh.module.video.aiot.config.AiServiceConfig; import com.viewsh.module.video.aiot.dao.AiAlgorithmMapper; import com.viewsh.module.video.aiot.service.IAiAlgorithmService; import com.viewsh.module.video.aiot.service.IAiConfigLogService; -import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import java.time.LocalDateTime; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -29,64 +27,6 @@ public class AiAlgorithmServiceImpl implements IAiAlgorithmService { @Autowired private IAiConfigLogService configLogService; - /** - * 预置算法定义,启动时自动校正数据库中的乱码数据 - * 注意:仅包含边缘端实际实现的算法 - */ - private static final Map PRESET_ALGORITHMS = new HashMap<>(); - static { - // algoCode -> {algoName, targetClass, description, paramSchema} - PRESET_ALGORITHMS.put("leave_post", new String[]{ - "离岗检测", "person", "检测人员是否在岗,支持工作时间段配置。算法抽帧频率:3帧/秒(固定)", - "{\"leave_countdown_sec\":{\"type\":\"int\",\"default\":300,\"min\":0},\"working_hours\":{\"type\":\"list\",\"default\":[]}}" - }); - PRESET_ALGORITHMS.put("intrusion", new String[]{ - "周界入侵检测", "person", "检测人员进入指定区域。算法抽帧频率:1帧/秒(固定)。持续检测到人5秒触发告警,持续无人180秒自动结束告警。消失确认期间短暂有人(<5秒)不影响倒计时。", - "{\"cooldown_seconds\":{\"type\":\"int\",\"default\":300,\"min\":0},\"confirm_seconds\":{\"type\":\"int\",\"default\":5,\"min\":1},\"confirm_intrusion_seconds\":{\"type\":\"int\",\"default\":5,\"min\":1},\"confirm_clear_seconds\":{\"type\":\"int\",\"default\":180,\"min\":1}}" - }); - PRESET_ALGORITHMS.put("illegal_parking", new String[]{ - "车辆违停检测", "car,truck,bus,motorcycle", "检测禁停区域内是否有车辆违规停放。确认车辆停留15秒后开始5分钟倒计时,超时触发告警。车辆离开30秒后自动结束告警。", - "{\"confirm_vehicle_sec\":{\"type\":\"int\",\"default\":15,\"min\":5},\"parking_countdown_sec\":{\"type\":\"int\",\"default\":300,\"min\":60},\"confirm_clear_sec\":{\"type\":\"int\",\"default\":30,\"min\":10},\"cooldown_sec\":{\"type\":\"int\",\"default\":600,\"min\":0}}" - }); - PRESET_ALGORITHMS.put("vehicle_congestion", new String[]{ - "车辆拥堵检测", "car,truck,bus,motorcycle", "检测区域内车辆是否拥堵。当平均车辆数达到阈值并持续60秒触发告警,车辆减少并持续120秒后自动结束告警。", - "{\"count_threshold\":{\"type\":\"int\",\"default\":3,\"min\":1},\"confirm_congestion_sec\":{\"type\":\"int\",\"default\":60,\"min\":10},\"confirm_clear_sec\":{\"type\":\"int\",\"default\":120,\"min\":10},\"cooldown_sec\":{\"type\":\"int\",\"default\":600,\"min\":0}}" - }); - } - - /** 系统级初始化使用的 creator/updater,@PostConstruct 无登录上下文时 MP 自动填充会留空 */ - private static final String SYSTEM_USER = "1"; - - @PostConstruct - public void initPresetAlgorithms() { - for (Map.Entry entry : PRESET_ALGORITHMS.entrySet()) { - String code = entry.getKey(); - String[] vals = entry.getValue(); - AiAlgorithm existing = algorithmMapper.queryByCode(code); - if (existing == null) { - AiAlgorithm algo = new AiAlgorithm(); - algo.setAlgoCode(code); - algo.setAlgoName(vals[0]); - algo.setTargetClass(vals[1]); - algo.setDescription(vals[2]); - algo.setParamSchema(vals[3]); - algo.setIsActive(true); - algo.setCreator(SYSTEM_USER); - algo.setUpdater(SYSTEM_USER); - algorithmMapper.add(algo); - log.info("[AI算法] 初始化预置算法: {}", code); - } else { - existing.setAlgoName(vals[0]); - existing.setTargetClass(vals[1]); - existing.setDescription(vals[2]); - existing.setParamSchema(vals[3]); - existing.setUpdater(SYSTEM_USER); - algorithmMapper.updateByCode(existing); - log.info("[AI算法] 校正预置算法数据: {}", code); - } - } - } - @Override public List queryAll() { return algorithmMapper.queryAll();