package com.vincent.rsf.server.ai.config; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.sql.DataSource; import java.sql.Connection; import java.sql.ResultSet; import java.util.Arrays; import java.util.List; @Component public class AiSchemaGuard { private static final List REQUIRED_TABLES = Arrays.asList( "sys_ai_chat_session", "sys_ai_chat_message", "sys_ai_prompt_template", "sys_ai_prompt_publish_log", "sys_ai_diagnosis_record", "sys_ai_diagnosis_plan", "sys_ai_call_log", "sys_ai_mcp_mount", "sys_ai_model_route", "sys_ai_diagnostic_tool_config" ); @Resource private DataSource dataSource; @PostConstruct public void validate() { try (Connection connection = dataSource.getConnection()) { for (String table : REQUIRED_TABLES) { if (!tableExists(connection, table)) { throw new IllegalStateException("AI feature table missing: " + table + ",请先执行 AI 迁移脚本"); } } } catch (IllegalStateException e) { throw e; } catch (Exception e) { throw new IllegalStateException("AI feature schema validation failed: " + e.getMessage(), e); } } private boolean tableExists(Connection connection, String tableName) throws Exception { try (ResultSet resultSet = connection.getMetaData().getTables(connection.getCatalog(), null, tableName, null)) { if (resultSet.next()) { return true; } } try (ResultSet resultSet = connection.getMetaData().getTables(connection.getCatalog(), null, tableName.toUpperCase(), null)) { if (resultSet.next()) { return true; } } try (ResultSet resultSet = connection.getMetaData().getTables(connection.getCatalog(), null, tableName.toLowerCase(), null)) { return resultSet.next(); } } }