sensitiveParams;
- }
-
- /**
- * 限流配置
- */
- @Data
- public static class RateLimitConfig {
- private Integer maxExecutionsPerMinute = 10;
- private Integer maxExecutionsPerDay = 100;
- }
-
- /**
- * 获取当前提供商配置
- */
- public ProviderConfig getCurrentProviderConfig() {
- if (providers == null || !providers.containsKey(provider)) {
- throw new IllegalStateException("未找到提供商配置: " + provider);
- }
- return providers.get(provider);
- }
-}
-
-
diff --git a/src/main/java/com/youlai/boot/platform/ai/config/SpringAiConfig.java b/src/main/java/com/youlai/boot/platform/ai/config/SpringAiConfig.java
new file mode 100644
index 00000000..699f3140
--- /dev/null
+++ b/src/main/java/com/youlai/boot/platform/ai/config/SpringAiConfig.java
@@ -0,0 +1,49 @@
+package com.youlai.boot.platform.ai.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.ai.chat.client.ChatClient;
+import org.springframework.ai.openai.OpenAiChatModel;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import com.youlai.boot.platform.ai.tools.UserTools;
+
+/**
+ * Spring AI 配置类
+ *
+ * 使用 Spring AI 自动配置,支持:
+ * - OpenAI
+ * - 通义千问(DashScope 兼容 OpenAI 协议)
+ * - DeepSeek(兼容 OpenAI 协议)
+ * - 其他兼容 OpenAI 协议的模型
+ *
+ * 配置方式:
+ * spring.ai.openai.api-key: xxx
+ * spring.ai.openai.base-url: xxx
+ * spring.ai.openai.chat.options.model: xxx
+ *
+ * @author Ray.Hao
+ * @since 3.0.0
+ */
+@Slf4j
+@Configuration
+@ConditionalOnProperty(prefix = "spring.ai.openai.chat", name = "enabled", havingValue = "true", matchIfMissing = false)
+public class SpringAiConfig {
+
+ /**
+ * 创建 ChatClient(Spring AI 核心客户端)
+ *
+ * OpenAiChatModel 由 Spring AI 自动配置创建
+ * 根据 spring.ai.openai.* 配置自动初始化
+ */
+ @Bean
+ public ChatClient chatClient(OpenAiChatModel chatModel, UserTools userTools) {
+ log.info("✅ Spring AI ChatClient 初始化成功");
+ log.info("📋 当前配置 - 模型: {}", chatModel.getDefaultOptions().getModel());
+ // 将 UserTools 注册为默认工具,所有调用都可使用
+ return ChatClient.builder(chatModel)
+ .defaultTools(userTools)
+ .build();
+ }
+}
+
diff --git a/src/main/java/com/youlai/boot/platform/ai/controller/AiCommandController.java b/src/main/java/com/youlai/boot/platform/ai/controller/AiCommandController.java
index 3597fdca..7a11f0b7 100644
--- a/src/main/java/com/youlai/boot/platform/ai/controller/AiCommandController.java
+++ b/src/main/java/com/youlai/boot/platform/ai/controller/AiCommandController.java
@@ -1,7 +1,14 @@
package com.youlai.boot.platform.ai.controller;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.youlai.boot.core.web.PageResult;
import com.youlai.boot.core.web.Result;
-import com.youlai.boot.platform.ai.model.dto.*;
+import com.youlai.boot.platform.ai.model.dto.AiExecuteRequestDTO;
+import com.youlai.boot.platform.ai.model.dto.AiParseRequestDTO;
+import com.youlai.boot.platform.ai.model.dto.AiParseResponseDTO;
+import com.youlai.boot.platform.ai.model.query.AiCommandPageQuery;
+import com.youlai.boot.platform.ai.model.vo.AiCommandRecordVO;
+import com.youlai.boot.platform.ai.service.AiCommandRecordService;
import com.youlai.boot.platform.ai.service.AiCommandService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -11,9 +18,8 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
-
/**
- * AI 命令控制器
+ * AI 命令控制器(基于 Spring AI)
*
* @author Ray.Hao
* @since 3.0.0
@@ -25,75 +31,60 @@ import org.springframework.web.bind.annotation.*;
@Slf4j
public class AiCommandController {
- private final AiCommandService aiCommandService;
+ private final AiCommandService aiCommandService;
+ private final AiCommandRecordService recordService;
- @Operation(summary = "解析自然语言命令")
- @PostMapping("/parse")
- public Result parseCommand(
- @RequestBody AiCommandRequestDTO request,
- HttpServletRequest httpRequest
- ) {
- log.info("收到AI命令解析请求: {}", request.getCommand());
+ @Operation(summary = "解析自然语言命令")
+ @PostMapping("/parse")
+ public Result parseCommand(
+ @RequestBody AiParseRequestDTO request,
+ HttpServletRequest httpRequest
+ ) {
+ log.info("收到AI命令解析请求: {}", request.getCommand());
- try {
- AiCommandResponseDTO response = aiCommandService.parseCommand(request, httpRequest);
- return Result.success(response);
- } catch (Exception e) {
- log.error("命令解析失败", e);
- return Result.success(AiCommandResponseDTO.builder()
- .success(false)
- .error(e.getMessage())
- .build());
- }
+ try {
+ AiParseResponseDTO response = aiCommandService.parseCommand(request, httpRequest);
+ return Result.success(response);
+ } catch (Exception e) {
+ log.error("命令解析失败", e);
+ return Result.success(AiParseResponseDTO.builder()
+ .success(false)
+ .error(e.getMessage())
+ .build());
}
+ }
- @Operation(summary = "执行已解析的命令")
- @PostMapping("/execute")
- public Result executeCommand(
- @RequestBody AiExecuteRequestDTO request,
- HttpServletRequest httpRequest
- ) {
- log.info("收到AI命令执行请求: {}", request.getFunctionCall().getName());
-
- try {
- AiExecuteResponseDTO response = aiCommandService.executeCommand(request, httpRequest);
- return Result.success(response);
- } catch (Exception e) {
- log.error("命令执行失败", e);
- return Result.success(AiExecuteResponseDTO.builder()
- .success(false)
- .error(e.getMessage())
- .build());
- }
+ @Operation(summary = "执行已解析的命令")
+ @PostMapping("/execute")
+ public Result