package com.wok.supportbot.config; import com.wok.supportbot.entity.AiModelConfig; import com.wok.supportbot.service.AiModelConfigService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; /** * 模型配置加载器 * 应用启动完成后,校验数据库中各应用类型的活跃配置是否存在 */ @Component @Slf4j public class ModelConfigLoader implements ApplicationListener { @Autowired private AiModelConfigService aiModelConfigService; @Value("${spring.ai.dashscope.api-key:}") private String dashscopeApiKey; @Override public void onApplicationEvent(ApplicationReadyEvent event) { log.info("========== AI 模型配置校验 =========="); try { checkAppTypeConfig("CHAT"); checkAppTypeConfig("EMBEDDING"); checkAppTypeConfig("RAG_REWRITE"); checkAppTypeConfig("RERANK"); log.info("========== AI 模型配置校验完成 =========="); } catch (Exception e) { log.warn("模型配置校验异常(不影响启动): {}", e.getMessage()); } } /** * 校验指定应用类型的数据库活跃配置是否存在 * 仅比较 API Key 一致性(对 DashScope 提供商的配置) */ private void checkAppTypeConfig(String appType) { AiModelConfig activeConfig = aiModelConfigService.getActiveConfigWithFullKey(appType); if (activeConfig == null) { log.warn(" [{}] ⚠️ 数据库中无活跃配置,请在管理页面配置", appType); return; } // 仅比较 API Key:如果 DB 配置的 provider 是 dashscope,对比 yml 中的 apiKey if ("dashscope".equals(activeConfig.getProvider()) && dashscopeApiKey != null && !dashscopeApiKey.isBlank() && !dashscopeApiKey.equals(activeConfig.getApiKey())) { log.warn(" [{}] ⚠️ DB 中的 API Key 与 application.yml 不一致!", appType); log.warn(" DB : apiKey={}****", AiModelConfigService.maskApiKey(activeConfig.getApiKey())); log.warn(" YML : apiKey={}****", AiModelConfigService.maskApiKey(dashscopeApiKey)); log.warn(" 提示:建议在管理页面统一管理 API Key,或保持 yml 与 DB 一致"); } else { log.info(" [{}] ✅ 活跃配置 [{}] provider={}", appType, activeConfig.getModelName(), activeConfig.getProvider()); } } }