Browse Source

feat:mcp-server

pudongliang 4 months ago
parent
commit
a59e63dfd5

+ 10 - 0
pom.xml

@@ -50,6 +50,16 @@
 
     <dependencies>
 
+        <!-- Source: https://mvnrepository.com/artifact/org.springframework.ai/spring-ai-starter-mcp-server -->
+        <!-- Spring AI 2.x.x (main branch) - Spring Boot 4.x
+        Spring AI 1.1.x (1.1.x branch) - Spring Boot 3.5.x -->
+        <dependency>
+            <groupId>org.springframework.ai</groupId>
+            <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
+            <version>2.0.0-M2</version>
+            <scope>compile</scope>
+        </dependency>
+        
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>

+ 24 - 1
src/main/java/com/moka/gdtauto/controller/AdPlanConfController.java

@@ -39,6 +39,8 @@ import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springaicommunity.mcp.annotation.McpTool;
+import org.springaicommunity.mcp.annotation.McpToolParam;
 import org.springframework.beans.BeanUtils;
 import org.springframework.web.bind.annotation.*;
 
@@ -475,7 +477,28 @@ public class AdPlanConfController {
             @AuthUser SysUser sysUser) {
         try {
             Page<AdPlanConf> page = adPlanConfService.getUserAdPlanConfs(
-                    sysUser.getId(), pageNum, pageSize);
+                    sysUser.getId(), pageNum, pageSize, false);
+            return Result.success(page, "查询成功");
+        } catch (Exception e) {
+            log.error("查询广告计划配置列表失败", e);
+            return Result.fail("查询广告计划配置列表失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 获取用户的广告计划配置列表(分页)
+     */
+    @Operation(summary = "获取广告计划配置列表", description = "分页获取当前用户的所有广告计划配置")
+    @McpTool(name = "get-my-ad-plan-config-list", description = "分页获取当前用户的所有广告计划配置")
+    public Result<Page<AdPlanConf>> getMyAdPlanConfigList(
+            @McpToolParam(description = "页码")
+            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @McpToolParam(description = "每页大小")
+            @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10") Integer pageSize,
+            @AuthUser SysUser sysUser) {
+        try {
+            Page<AdPlanConf> page = adPlanConfService.getUserAdPlanConfs(
+                    sysUser.getId(), pageNum, pageSize, true);
             return Result.success(page, "查询成功");
         } catch (Exception e) {
             log.error("查询广告计划配置列表失败", e);

+ 9 - 0
src/main/java/com/moka/gdtauto/controller/AdPlanController.java

@@ -10,6 +10,9 @@ import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+
+import org.springaicommunity.mcp.annotation.McpTool;
+import org.springaicommunity.mcp.annotation.McpToolParam;
 import org.springframework.web.bind.annotation.*;
 
 /**
@@ -31,17 +34,23 @@ public class AdPlanController {
     /**
      * 获取广告计划列表(分页)
      */
+    @McpTool(name = "get-ad-plan-list", description = "分页获取广告计划列表,可按账户ID和状态筛选")
     @Operation(summary = "获取广告计划列表", description = "分页获取广告计划列表,可按账户ID和状态筛选")
     @GetMapping("/list")
     public Result<Page<AdPlan>> getAdPlans(
+            @McpToolParam(description = "配置ID")
             @Parameter(description = "配置ID", example = "123456")
             @RequestParam Long confId,
+            @McpToolParam(description = "账户ID,可选", required = false)
             @Parameter(description = "账户ID,可选", example = "123456")
             @RequestParam(required = false) Long accountId,
+            @McpToolParam(description = "状态,可选:1-待执行,2-执行中,3-失败,4-已结束", required = false)
             @Parameter(description = "状态,可选:1-待执行,2-执行中,3-失败,4-已结束", example = "1")
             @RequestParam(required = false) Integer status,
+            @McpToolParam(description = "页码", required = false)
             @Parameter(description = "页码", example = "1")
             @RequestParam(defaultValue = "1") Integer pageNum,
+            @McpToolParam(description = "每页大小", required = false)
             @Parameter(description = "每页大小", example = "10")
             @RequestParam(defaultValue = "10") Integer pageSize) {
         try {

+ 17 - 0
src/main/java/com/moka/gdtauto/controller/OssFileController.java

@@ -11,6 +11,11 @@ import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+
+import org.springaicommunity.mcp.annotation.McpTool;
+import org.springaicommunity.mcp.annotation.McpToolParam;
+import org.springframework.ai.tool.annotation.Tool;
+import org.springframework.ai.tool.annotation.ToolParam;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -32,15 +37,20 @@ public class OssFileController {
     /**
      * 上传文件
      */
+    @McpTool(name = "upload-file", description = "上传文件到OSS并记录")
     @Operation(summary = "上传文件", description = "上传文件到OSS并记录")
     @PostMapping("/upload")
     public Result<OssFile> uploadFile(
+            @McpToolParam(description = "文件", required = true)
             @Parameter(description = "文件", required = true)
             @RequestParam("file") MultipartFile file,
+            @McpToolParam(description = "存储文件夹路径,如:images/、videos/")
             @Parameter(description = "存储文件夹路径,如:images/、videos/")
             @RequestParam(value = "folder", required = false, defaultValue = "") String folder,
+            @McpToolParam(description = "文件类型,如:image、video、document")
             @Parameter(description = "文件类型,如:image、video、document")
             @RequestParam(value = "fileType", required = false, defaultValue = "document") String fileType,
+            @ToolParam(description = "业务分类(1:创意 2:品牌形象)")
             @Parameter(description = "业务分类(1:创意 2:品牌形象)")
             @RequestParam(value = "businessType", required = false) Integer businessType,
             @AuthUser SysUser sysUser) {
@@ -68,14 +78,21 @@ public class OssFileController {
     /**
      * 分页查询文件列表
      */
+    @McpTool(name = "list-files", description = "分页查询文件列表")
     @Operation(summary = "分页查询文件列表", description = "根据条件分页查询文件列表")
     @GetMapping("/list")
     public Result<Page<OssFile>> listFiles(
+            @McpToolParam(description = "页码")
             @Parameter(description = "页码") @RequestParam(defaultValue = "1") Long page,
+            @McpToolParam(description = "每页数量")
             @Parameter(description = "每页数量") @RequestParam(defaultValue = "10") Long size,
+            @McpToolParam(description = "文件类型", required = false)
             @Parameter(description = "文件类型") @RequestParam(required = false) String fileType,
+            @McpToolParam(description = "业务分类(1:创意 2:品牌形象)", required = false)
             @Parameter(description = "业务分类(1:创意 2:品牌形象)") @RequestParam(required = false) Integer businessType,
+            @McpToolParam(description = "文件名(模糊查询)", required = false)
             @Parameter(description = "文件名(模糊查询)") @RequestParam(required = false) String fileName,
+            @McpToolParam(description = "创建人id", required = false)
             @Parameter(description = "创建人id") @RequestParam(required = false) Long userId) {
         try {
             Page<OssFile> result = ossFileService.listFiles(page, size, fileType, businessType, fileName, userId);

+ 13 - 0
src/main/java/com/moka/gdtauto/controller/SysUserController.java

@@ -11,6 +11,9 @@ import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+
+import org.springaicommunity.mcp.annotation.McpTool;
+import org.springaicommunity.mcp.annotation.McpToolParam;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.HashMap;
@@ -43,10 +46,16 @@ public class SysUserController {
         summary = "用户登录",
         description = "通过工号和密码进行登录,返回用户信息和实名认证状态"
     )
+    @McpTool(
+        name = "login",
+        description = "登录系统获取loginToken信息,放入请求头X-Login-Token"
+    )
     @PostMapping("/login")
     public Result<Map<String, Object>> login(
+            @McpToolParam(description = "工号", required = true)
             @Parameter(description = "工号", required = true, example = "12458")
             @RequestParam String jobNumber,
+            @McpToolParam(description = "密码", required = true)
             @Parameter(description = "密码", required = true, example = "123456")
             @RequestParam String password) {
         try {
@@ -124,6 +133,10 @@ public class SysUserController {
         summary = "获取当前登录用户信息",
         description = "通过 @AuthUser 注解自动获取当前登录用户,无需传递参数"
     )
+    @McpTool(
+        name = "get-current-user",
+        description = "登录后获取当前登录用户信息"
+    )
     @GetMapping("/current")
     public Result<Map<String, Object>> getCurrentUser(@AuthUser SysUser currentUser) {
         try {

+ 1 - 1
src/main/java/com/moka/gdtauto/service/AdPlanConfService.java

@@ -49,7 +49,7 @@ public interface AdPlanConfService extends IService<AdPlanConf> {
      * @param pageSize 每页大小
      * @return 配置分页列表
      */
-    Page<AdPlanConf> getUserAdPlanConfs(Long userId, Integer pageNum, Integer pageSize);
+    Page<AdPlanConf> getUserAdPlanConfs(Long userId, Integer pageNum, Integer pageSize, boolean isMy);
 
     /**
      * 获取广告计划配置详情

+ 2 - 1
src/main/java/com/moka/gdtauto/service/impl/AdPlanConfServiceImpl.java

@@ -433,11 +433,12 @@ public class AdPlanConfServiceImpl extends ServiceImpl<AdPlanConfMapper, AdPlanC
     }
 
     @Override
-    public Page<AdPlanConf> getUserAdPlanConfs(Long userId, Integer pageNum, Integer pageSize) {
+    public Page<AdPlanConf> getUserAdPlanConfs(Long userId, Integer pageNum, Integer pageSize, boolean isMy) {
         Page<AdPlanConf> page = new Page<>(pageNum, pageSize);
 
         LambdaQueryWrapper<AdPlanConf> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper.eq(AdPlanConf::getDeleted, 0)
+                .eq(isMy, AdPlanConf::getUserId, userId)
                 .orderByDesc(AdPlanConf::getCreateTime);
 
         return this.page(page, queryWrapper);

+ 7 - 0
src/main/resources/application.yml

@@ -8,6 +8,13 @@ spring:
       max-request-size: 100MB
   profiles:
     active: test
+  # https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-starter-docs.html
+  ai:
+    mcp:
+      server:
+        name: "腾讯快速投放"
+        version: "2.0.0"
+        sse-endpoint: /mcp/sse
   
   # Jackson配置
   jackson: