refactor(video): 预置 AI 算法改为 SQL 种子数据,移除 @PostConstruct 初始化
原 AiAlgorithmServiceImpl.initPresetAlgorithms() 在 @PostConstruct 里插入 4 条预置算法,带来两个问题: 1. 启动时无登录上下文,MP 自动填充 creator 失效 → 启动失败 2. 算法清单硬编码在 Java 代码,迭代要重编译发布 改为 video.sql 种子数据管理: - video.sql 的预置算法 INSERT 扩展为 4 条(leave_post / intrusion / illegal_parking / vehicle_congestion),参数 schema 与边缘端对齐 - 使用 ON DUPLICATE KEY UPDATE 保证幂等:新库初始化 + 存量库升级 都走同一条语句,param_schema / description 会被自动校正 - 保留用户侧可修改的字段(is_active / global_params)不被覆盖 代码层: - 删除 initPresetAlgorithms() 方法与 PRESET_ALGORITHMS 静态 Map - 删除 SYSTEM_USER 常量 - 删除 @PostConstruct / HashMap 相关 import - 保留 syncFromEdge() 作为边缘端主动同步的运行时入口 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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<String, String[]> 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<String, String[]> 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<AiAlgorithm> queryAll() {
|
||||
return algorithmMapper.queryAll();
|
||||
|
||||
Reference in New Issue
Block a user