liu
2026-10-19 e373bbe57d3782260787622c7aaf2bb9aa01fffe
fix(server): 排除 Spring AI 自动配置并升级 easy-trans

- 在启动类排除 Spring AI 向量库/模型自动配置,避免 vectorStore bean 冲突及未配置 apiKey 时启动失败
- easy-trans 升级至 4.0.2
- 修正数采文档实时刷新间隔描述(30 秒 -> 30 分钟)

Co-Authored-By: Claude <noreply@anthropic.com>
已修改3个文件
51 ■■■■■ 文件已修改
docs/dv_telemetry_integration.md 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-dependencies/pom.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-server/src/main/java/cn/iocoder/yudao/server/YudaoServerApplication.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/dv_telemetry_integration.md
@@ -10,7 +10,7 @@
## 业务流程与数据带入
1. **拉取数据**:页面点击「拉取最新数据」→ 调 `/mes/dv/telemetry/pull` → 后端调外部数采接口 `GET /api/jxjs/mesTb/getDeviceDetails`(近 5 分钟设备数据)→ 逐条写入 `mes_dv_telemetry` → 返回本次新增条数/设备数/拉取时间。
2. **实时查看**:实时数据 Tab 调 `/mes/dv/telemetry/latest`,按「设备+信号」去重保留最新一条;可开启「实时自动刷新」每 30 秒轮询一次。
2. **实时查看**:实时数据 Tab 调 `/mes/dv/telemetry/latest`,按「设备+信号」去重保留最新一条;可开启「实时自动刷新」每 30 分钟轮询一次。
3. **历史查看**:历史记录 Tab 调 `/mes/dv/telemetry/page` 分页,支持设备名称/信号名称/是否异常/遥测时间区间过滤。
4. **定时拉取**:系统内置定时任务「设备数采数据拉取」每 5 分钟自动拉取一次,避免近 5 分钟窗口数据丢失(页面无需感知)。
5. **设备关联**:设备台账表单手工维护「数采设备ID」(`tb_device_id`,对应外部数采 `tbDeviceId`);台账详情「数采数据」Tab 用该 ID 调 `/latest?tbDeviceId=xx` 展示该设备实时信号。未填数采设备ID时该 Tab 置灰。
yudao-dependencies/pom.xml
@@ -27,7 +27,7 @@
        <mybatis-plus.version>3.5.16</mybatis-plus.version>
        <mybatis-plus-join.version>1.5.7</mybatis-plus-join.version>
        <dynamic-datasource.version>4.5.0</dynamic-datasource.version>
        <easy-trans.version>3.1.5</easy-trans.version>
        <easy-trans.version>4.0.2</easy-trans.version>
        <redisson.version>4.6.1</redisson.version>
        <dm8.jdbc.version>8.1.3.140</dm8.jdbc.version>
        <kingbase.jdbc.version>9.0.1.jre7</kingbase.jdbc.version>
yudao-server/src/main/java/cn/iocoder/yudao/server/YudaoServerApplication.java
@@ -1,6 +1,24 @@
package cn.iocoder.yudao.server;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.model.anthropic.autoconfigure.AnthropicChatAutoConfiguration;
import org.springframework.ai.model.deepseek.autoconfigure.DeepSeekChatAutoConfiguration;
import org.springframework.ai.model.google.genai.autoconfigure.chat.GoogleGenAiChatAutoConfiguration;
import org.springframework.ai.model.google.genai.autoconfigure.embedding.GoogleGenAiEmbeddingConnectionAutoConfiguration;
import org.springframework.ai.model.google.genai.autoconfigure.embedding.GoogleGenAiTextEmbeddingAutoConfiguration;
import org.springframework.ai.model.openai.autoconfigure.OpenAiAudioSpeechAutoConfiguration;
import org.springframework.ai.model.openai.autoconfigure.OpenAiAudioTranscriptionAutoConfiguration;
import org.springframework.ai.model.openai.autoconfigure.OpenAiChatAutoConfiguration;
import org.springframework.ai.model.openai.autoconfigure.OpenAiEmbeddingAutoConfiguration;
import org.springframework.ai.model.openai.autoconfigure.OpenAiImageAutoConfiguration;
import org.springframework.ai.model.openai.autoconfigure.OpenAiModerationAutoConfiguration;
import org.springframework.ai.model.ollama.autoconfigure.OllamaApiAutoConfiguration;
import org.springframework.ai.model.ollama.autoconfigure.OllamaChatAutoConfiguration;
import org.springframework.ai.model.ollama.autoconfigure.OllamaEmbeddingAutoConfiguration;
import org.springframework.ai.model.stabilityai.autoconfigure.StabilityAiImageAutoConfiguration;
import org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreAutoConfiguration;
import org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreAutoConfiguration;
import org.springframework.ai.vectorstore.redis.autoconfigure.RedisVectorStoreAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
@@ -16,7 +34,34 @@
 */
@Slf4j
@SuppressWarnings("SpringComponentScan") // 忽略 IDEA 无法识别 ${yudao.info.base-package}
@SpringBootApplication(scanBasePackages = {"${yudao.info.base-package}.server", "${yudao.info.base-package}.module"})
@SpringBootApplication(scanBasePackages = {"${yudao.info.base-package}.server", "${yudao.info.base-package}.module"},
        // 注意:这里排除的 Spring AI 自动配置,与各 profile 的 spring.autoconfigure.exclude 保持一致,但写在代码里的
        // 原因是:注解里的排除项与 yaml 里的排除项是「并集」,不会被外部 profile 配置文件覆盖,保证换任何 profile 都能正常启动。
        // 1. 向量库:AI 模块由 AiModelFactoryImpl 手动构建 VectorStore,三个自动配置同时启用会争抢 vectorStore 这个 bean 名
        // 2. 模型:AI 模块的模型由 AiModelFactoryImpl 手动构建(走 DB 里 ai_model 配置的 apiKey),不需要 Spring AI 的模型 Bean;
        //    且未配置 api-key 时自动配置会在启动阶段直接抛「API key cannot be empty.」
        exclude = {
                // ========== 向量库自动配置 ==========
                QdrantVectorStoreAutoConfiguration.class,
                RedisVectorStoreAutoConfiguration.class,
                MilvusVectorStoreAutoConfiguration.class,
                // ========== 模型自动配置 ==========
                OpenAiChatAutoConfiguration.class,
                OpenAiEmbeddingAutoConfiguration.class,
                OpenAiImageAutoConfiguration.class,
                OpenAiAudioSpeechAutoConfiguration.class,
                OpenAiAudioTranscriptionAutoConfiguration.class,
                OpenAiModerationAutoConfiguration.class,
                DeepSeekChatAutoConfiguration.class,
                AnthropicChatAutoConfiguration.class,
                GoogleGenAiChatAutoConfiguration.class,
                GoogleGenAiEmbeddingConnectionAutoConfiguration.class,
                GoogleGenAiTextEmbeddingAutoConfiguration.class,
                OllamaApiAutoConfiguration.class,
                OllamaChatAutoConfiguration.class,
                OllamaEmbeddingAutoConfiguration.class,
                StabilityAiImageAutoConfiguration.class,
        })
public class YudaoServerApplication {
    public static void main(String[] args) {