pudongliang 4 месяцев назад
Родитель
Сommit
f09e51f8aa
42 измененных файлов с 223 добавлено и 120 удалено
  1. 1 1
      portal/dist/assets/accountGroup-B4TxRTCi.js
  2. 1 1
      portal/dist/assets/adAutoConf-zLeV_gJw.js
  3. 1 1
      portal/dist/assets/adPlanConf-CHK-ztey.js
  4. 1 1
      portal/dist/assets/auth-CDge7bHP.js
  5. 1 1
      portal/dist/assets/conversion-CXLG4o95.js
  6. 0 0
      portal/dist/assets/detail-32cgSeS_.js
  7. 1 1
      portal/dist/assets/drama-BWFi-ffY.js
  8. 0 0
      portal/dist/assets/edit-Bx1r3GtK.js
  9. 0 0
      portal/dist/assets/index-51qt4ivU.js
  10. 0 0
      portal/dist/assets/index-BILHRf6p.js
  11. 0 0
      portal/dist/assets/index-BgjG-czG.js
  12. 0 0
      portal/dist/assets/index-BsHe-3kH.js
  13. 0 0
      portal/dist/assets/index-Bt8_ALd4.js
  14. 1 1
      portal/dist/assets/index-Bwbh2Xl0.js
  15. 0 0
      portal/dist/assets/index-C0Oa519t.js
  16. 0 0
      portal/dist/assets/index-CKq68tTC.js
  17. 0 0
      portal/dist/assets/index-CaqLJi3D.js
  18. 0 0
      portal/dist/assets/index-Ch6VHOhb.js
  19. 0 0
      portal/dist/assets/index-CmVqMP00.js
  20. 0 0
      portal/dist/assets/index-CnthAj5t.js
  21. 0 0
      portal/dist/assets/index-DH4rsdSG.js
  22. 0 0
      portal/dist/assets/index-DaKQLCFY.js
  23. 0 0
      portal/dist/assets/index-Dh-g-zru.js
  24. 0 0
      portal/dist/assets/index-Dw5Q0gG5.js
  25. 0 0
      portal/dist/assets/index-TC61sJlP.js
  26. 1 1
      portal/dist/assets/loadPageConf-PLGrQsYQ.js
  27. 1 1
      portal/dist/assets/ossFile-CJfU0j4P.js
  28. 0 0
      portal/dist/assets/request-CLGY40Ww.js
  29. 1 1
      portal/dist/assets/user-BHGHoXtD.js
  30. 1 1
      portal/dist/index.html
  31. 26 0
      portal/docs/conf/conf.d/front.conf
  32. 1 1
      portal/src/router/index.js
  33. 4 7
      src/main/java/com/moka/gdtauto/controller/AdPlanConfController.java
  34. 6 11
      src/main/java/com/moka/gdtauto/controller/AdPlanController.java
  35. 105 0
      src/main/java/com/moka/gdtauto/controller/McpController.java
  36. 0 15
      src/main/java/com/moka/gdtauto/controller/OssFileController.java
  37. 0 12
      src/main/java/com/moka/gdtauto/controller/SysUserController.java
  38. 8 6
      src/main/java/com/moka/gdtauto/interceptor/LoginTokenInterceptor.java
  39. 2 5
      src/main/java/com/moka/gdtauto/service/AdPlanConfService.java
  40. 59 49
      src/main/java/com/moka/gdtauto/service/impl/AdPlanConfServiceImpl.java
  41. 0 2
      src/main/java/com/moka/gdtauto/service/impl/AdPlanServiceImpl.java
  42. 1 1
      src/main/resources/application.yml

+ 1 - 1
portal/dist/assets/accountGroup-COQYR1c4.js → portal/dist/assets/accountGroup-B4TxRTCi.js

@@ -1 +1 @@
-import{r as u}from"./request-CVWVJtwb.js";function c(t){return u({url:"/api/account-group/create",method:"post",data:t})}function e(t){return u({url:"/api/account-group/update",method:"post",data:t})}function n(t){return u({url:`/api/account-group/${t}`,method:"delete"})}function a(t=1,o=10){return u({url:"/api/account-group/list",method:"get",params:{pageNum:t,pageSize:o}})}function p(){return u({url:"/api/account-group/all",method:"get"})}function i(t){return u({url:`/api/account-group/${t}/accounts`,method:"get"})}export{i as a,p as b,c,n as d,a as g,e as u};
+import{r as u}from"./request-CLGY40Ww.js";function c(t){return u({url:"/api/account-group/create",method:"post",data:t})}function e(t){return u({url:"/api/account-group/update",method:"post",data:t})}function n(t){return u({url:`/api/account-group/${t}`,method:"delete"})}function a(t=1,o=10){return u({url:"/api/account-group/list",method:"get",params:{pageNum:t,pageSize:o}})}function p(){return u({url:"/api/account-group/all",method:"get"})}function i(t){return u({url:`/api/account-group/${t}/accounts`,method:"get"})}export{i as a,p as b,c,n as d,a as g,e as u};

+ 1 - 1
portal/dist/assets/adAutoConf-CDFXX5F3.js → portal/dist/assets/adAutoConf-zLeV_gJw.js

@@ -1 +1 @@
-import{r as e}from"./request-CVWVJtwb.js";function u(t){return e({url:"/api/ad-auto-conf/list",method:"get",params:t})}function n(t){return e({url:`/api/ad-auto-conf/${t}`,method:"get"})}function a(t){return e({url:"/api/ad-auto-conf",method:"post",data:t})}function r(t){return e({url:"/api/ad-auto-conf/update",method:"post",data:t})}function i(t){return e({url:`/api/ad-auto-conf/execute?id=${t}`,method:"post"})}function d(t){return e({url:"/api/execute-log/list",method:"get",params:t})}function c(t){return e({url:"/api/execute-log/getChildLog",method:"get",params:t})}export{c as a,d as b,n as c,i as e,u as g,a as s,r as u};
+import{r as e}from"./request-CLGY40Ww.js";function u(t){return e({url:"/api/ad-auto-conf/list",method:"get",params:t})}function n(t){return e({url:`/api/ad-auto-conf/${t}`,method:"get"})}function a(t){return e({url:"/api/ad-auto-conf",method:"post",data:t})}function r(t){return e({url:"/api/ad-auto-conf/update",method:"post",data:t})}function i(t){return e({url:`/api/ad-auto-conf/execute?id=${t}`,method:"post"})}function d(t){return e({url:"/api/execute-log/list",method:"get",params:t})}function c(t){return e({url:"/api/execute-log/getChildLog",method:"get",params:t})}export{c as a,d as b,n as c,i as e,u as g,a as s,r as u};

+ 1 - 1
portal/dist/assets/adPlanConf-DUgUKa3Q.js → portal/dist/assets/adPlanConf-CHK-ztey.js

@@ -1 +1 @@
-import{r as a}from"./request-CVWVJtwb.js";function d(n){return a({url:"/api/ad-plan-conf/reCreate",method:"post",data:n})}function o(n){return a({url:"/api/ad-plan-conf/generate-plan",method:"post",data:n})}function u(n){return a({url:`/api/ad-plan-conf/reGeneratePlan/${n}`,method:"get"})}function l(n){return a({url:`/api/ad-plan-conf/syncSystemStatus/${n}`,method:"get"})}function p(n){return a({url:"/api/ad-plan-conf/create",method:"post",data:n})}function s(n){return a({url:"/api/ad-plan-conf/update",method:"post",data:n})}function i(n=1,e=10,t={}){return a({url:"/api/ad-plan-conf/list",method:"get",params:{pageNum:n,pageSize:e,...t}})}function f(n){return a({url:`/api/ad-plan-conf/${n}`,method:"get"})}function c(n){return a({url:"/api/ad-plan/list",method:"get",params:n})}function g(n){return a({url:`/api/ad-plan-creative/plan/${n}`,method:"get"})}function m(n){return a({url:"/api/ad-plan-conf/gdtSuspendByConfId",params:{confId:n},method:"get"})}function h(n){return a({url:"/api/ad-plan-conf/gdtDeleteByConfId",params:{confId:n},method:"get"})}function C(n,e){return a({url:`/api/ad-plan-conf/gdtSuspendByPlanIds/${n}`,method:"post",data:e})}function P(n,e){return a({url:`/api/ad-plan-conf/gdtDeleteByPlanIds/${n}`,method:"post",data:e})}function y(n=[]){return a({url:"/api/ad-plan-conf/getOneCreativeImage",method:"post",data:n})}function I(){return a({url:"/api/ad-plan-conf/getOneBrandImage",method:"get"})}function B(n=[]){return a({url:"/api/ad-plan-conf/getOneCreativeVideo",method:"post",data:n})}export{y as a,I as b,B as c,o as d,p as e,f,i as g,c as h,h as i,C as j,P as k,l,u as m,g as n,d as r,m as s,s as u};
+import{r as a}from"./request-CLGY40Ww.js";function d(n){return a({url:"/api/ad-plan-conf/reCreate",method:"post",data:n})}function o(n){return a({url:"/api/ad-plan-conf/generate-plan",method:"post",data:n})}function u(n){return a({url:`/api/ad-plan-conf/reGeneratePlan/${n}`,method:"get"})}function l(n){return a({url:`/api/ad-plan-conf/syncSystemStatus/${n}`,method:"get"})}function p(n){return a({url:"/api/ad-plan-conf/create",method:"post",data:n})}function s(n){return a({url:"/api/ad-plan-conf/update",method:"post",data:n})}function i(n=1,e=10,t={}){return a({url:"/api/ad-plan-conf/list",method:"get",params:{pageNum:n,pageSize:e,...t}})}function f(n){return a({url:`/api/ad-plan-conf/${n}`,method:"get"})}function c(n){return a({url:"/api/ad-plan/list",method:"get",params:n})}function g(n){return a({url:`/api/ad-plan-creative/plan/${n}`,method:"get"})}function m(n){return a({url:"/api/ad-plan-conf/gdtSuspendByConfId",params:{confId:n},method:"get"})}function h(n){return a({url:"/api/ad-plan-conf/gdtDeleteByConfId",params:{confId:n},method:"get"})}function C(n,e){return a({url:`/api/ad-plan-conf/gdtSuspendByPlanIds/${n}`,method:"post",data:e})}function P(n,e){return a({url:`/api/ad-plan-conf/gdtDeleteByPlanIds/${n}`,method:"post",data:e})}function y(n=[]){return a({url:"/api/ad-plan-conf/getOneCreativeImage",method:"post",data:n})}function I(){return a({url:"/api/ad-plan-conf/getOneBrandImage",method:"get"})}function B(n=[]){return a({url:"/api/ad-plan-conf/getOneCreativeVideo",method:"post",data:n})}export{y as a,I as b,B as c,o as d,p as e,f,i as g,c as h,h as i,C as j,P as k,l,u as m,g as n,d as r,m as s,s as u};

+ 1 - 1
portal/dist/assets/auth-B30T2fwd.js → portal/dist/assets/auth-CDge7bHP.js

@@ -1 +1 @@
-import{r as t}from"./request-CVWVJtwb.js";function i(){return t({url:"/api/gdt/auth/authorize-url",method:"get"})}function n(r){return t({url:"/api/gdt/auth/refresh",method:"post",params:r})}function u(){return t({url:"/api/gdt/auth/list",method:"get"})}function a(){return u()}function o(){return t({url:"/api/gdt/auth/expiring",method:"get"})}export{o as a,a as b,i as g,u as l,n as r};
+import{r as t}from"./request-CLGY40Ww.js";function i(){return t({url:"/api/gdt/auth/authorize-url",method:"get"})}function n(r){return t({url:"/api/gdt/auth/refresh",method:"post",params:r})}function u(){return t({url:"/api/gdt/auth/list",method:"get"})}function a(){return u()}function o(){return t({url:"/api/gdt/auth/expiring",method:"get"})}export{o as a,a as b,i as g,u as l,n as r};

+ 1 - 1
portal/dist/assets/conversion-DzNkwnFS.js → portal/dist/assets/conversion-CXLG4o95.js

@@ -1 +1 @@
-import{r as t}from"./request-CVWVJtwb.js";function e(n,o){return t({url:"/api/gdt/conversion/sync",method:"post",params:{orgAccountId:n,accountId:o}})}function s(n=1,o=20){return t({url:"/api/gdt/conversion/list",method:"get",params:{page:n,pageSize:o}})}function i(n){return t({url:"/api/gdt/conversion/detail",method:"get",params:{conversionId:n}})}function a(){return t({url:"/api/gdt/conversion/all",method:"get"})}export{s as a,i as b,a as g,e as s};
+import{r as t}from"./request-CLGY40Ww.js";function e(n,o){return t({url:"/api/gdt/conversion/sync",method:"post",params:{orgAccountId:n,accountId:o}})}function s(n=1,o=20){return t({url:"/api/gdt/conversion/list",method:"get",params:{page:n,pageSize:o}})}function i(n){return t({url:"/api/gdt/conversion/detail",method:"get",params:{conversionId:n}})}function a(){return t({url:"/api/gdt/conversion/all",method:"get"})}export{s as a,i as b,a as g,e as s};

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/detail-32cgSeS_.js


+ 1 - 1
portal/dist/assets/drama-CKDIUDLl.js → portal/dist/assets/drama-BWFi-ffY.js

@@ -1 +1 @@
-import{r as t}from"./request-CVWVJtwb.js";function n(a){return t({url:"/api/gdt/asset/drama/sync",method:"post",params:{accountId:a}})}function m(a=1,s=20,r=""){return t({url:"/api/gdt/asset/drama/list",method:"get",params:{dramaName:r,page:a,pageSize:s}})}function d(a){return t({url:"/api/gdt/asset/drama/myDramaAssets",method:"get",params:{dramaName:a}})}function o(){return t({url:"/api/gdt/asset/drama/sync/conf/myConf",method:"get"})}function u(a){return t({url:"/api/gdt/asset/drama/sync/conf/add",method:"post",data:a})}function i(a){return t({url:"/api/gdt/asset/drama/sync/conf/delete",method:"post",params:{id:a}})}export{o as a,u as b,i as d,m as g,d as m,n as s};
+import{r as t}from"./request-CLGY40Ww.js";function n(a){return t({url:"/api/gdt/asset/drama/sync",method:"post",params:{accountId:a}})}function m(a=1,s=20,r=""){return t({url:"/api/gdt/asset/drama/list",method:"get",params:{dramaName:r,page:a,pageSize:s}})}function d(a){return t({url:"/api/gdt/asset/drama/myDramaAssets",method:"get",params:{dramaName:a}})}function o(){return t({url:"/api/gdt/asset/drama/sync/conf/myConf",method:"get"})}function u(a){return t({url:"/api/gdt/asset/drama/sync/conf/add",method:"post",data:a})}function i(a){return t({url:"/api/gdt/asset/drama/sync/conf/delete",method:"post",params:{id:a}})}export{o as a,u as b,i as d,m as g,d as m,n as s};

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/edit-Bx1r3GtK.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-51qt4ivU.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-BILHRf6p.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-BgjG-czG.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-BsHe-3kH.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-Bt8_ALd4.js


Разница между файлами не показана из-за своего большого размера
+ 1 - 1
portal/dist/assets/index-Bwbh2Xl0.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-C0Oa519t.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-CKq68tTC.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-CaqLJi3D.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-Ch6VHOhb.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-CmVqMP00.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-CnthAj5t.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-DH4rsdSG.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-DaKQLCFY.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-Dh-g-zru.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-Dw5Q0gG5.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/index-TC61sJlP.js


+ 1 - 1
portal/dist/assets/loadPageConf-DJXySktp.js → portal/dist/assets/loadPageConf-PLGrQsYQ.js

@@ -1 +1 @@
-import{r as o}from"./request-CVWVJtwb.js";function t(a){return o({url:"/api/load-page-conf/list",method:"get",params:a})}function n(a){return o({url:`/api/load-page-conf/${a}`,method:"get"})}function r(a){return o({url:"/api/load-page-conf",method:"post",data:a})}function u(a){return o({url:"/api/load-page-conf",method:"put",data:a})}function d(){return o({url:"/api/load-page-conf/all",method:"get"})}export{t as a,n as b,r as c,d as g,u};
+import{r as o}from"./request-CLGY40Ww.js";function t(a){return o({url:"/api/load-page-conf/list",method:"get",params:a})}function n(a){return o({url:`/api/load-page-conf/${a}`,method:"get"})}function r(a){return o({url:"/api/load-page-conf",method:"post",data:a})}function u(a){return o({url:"/api/load-page-conf",method:"put",data:a})}function d(){return o({url:"/api/load-page-conf/all",method:"get"})}export{t as a,n as b,r as c,d as g,u};

+ 1 - 1
portal/dist/assets/ossFile-Ba2GTtTJ.js → portal/dist/assets/ossFile-CJfU0j4P.js

@@ -1 +1 @@
-import{r as t}from"./request-CVWVJtwb.js";function i(e){return t({timeout:12e5,url:"/api/oss-file/upload",method:"post",data:e,headers:{"Content-Type":"multipart/form-data"}})}function o(e){return t({url:"/api/oss-file/list",method:"get",params:e})}function r(e){return t({url:`/api/oss-file/${e}`,method:"delete"})}function l(e){return t({url:"/api/oss-file/batch",method:"delete",params:{fileIds:e}})}export{l as b,r as d,o as g,i as u};
+import{r as t}from"./request-CLGY40Ww.js";function i(e){return t({timeout:12e5,url:"/api/oss-file/upload",method:"post",data:e,headers:{"Content-Type":"multipart/form-data"}})}function o(e){return t({url:"/api/oss-file/list",method:"get",params:e})}function r(e){return t({url:`/api/oss-file/${e}`,method:"delete"})}function l(e){return t({url:"/api/oss-file/batch",method:"delete",params:{fileIds:e}})}export{l as b,r as d,o as g,i as u};

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
portal/dist/assets/request-CLGY40Ww.js


+ 1 - 1
portal/dist/assets/user-CD_NQe75.js → portal/dist/assets/user-BHGHoXtD.js

@@ -1 +1 @@
-import{r as e}from"./request-CVWVJtwb.js";function t(){return e({url:"/api/user/list",method:"get"})}function u(r){return e({url:"/api/user/info",method:"get",params:r})}function n(r){return e({url:"/api/user/user-token-url",method:"get",params:r})}function o(r){return e({url:"/api/user/login",method:"post",params:r})}function a(r){return e({url:"/api/user/change-password",method:"post",params:r})}function i(r){return e({url:"/api/user/save",method:"post",params:r})}export{u as a,t as b,a as c,n as g,o as l,i as s};
+import{r as e}from"./request-CLGY40Ww.js";function t(){return e({url:"/api/user/list",method:"get"})}function u(r){return e({url:"/api/user/info",method:"get",params:r})}function n(r){return e({url:"/api/user/user-token-url",method:"get",params:r})}function o(r){return e({url:"/api/user/login",method:"post",params:r})}function a(r){return e({url:"/api/user/change-password",method:"post",params:r})}function i(r){return e({url:"/api/user/save",method:"post",params:r})}export{u as a,t as b,a as c,n as g,o as l,i as s};

+ 1 - 1
portal/dist/index.html

@@ -5,7 +5,7 @@
     <link rel="icon" type="image/svg+xml" href="/vite.svg" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>腾讯广告自动化管理后台</title>
-    <script type="module" crossorigin src="/assets/index-D1wY3FFt.js"></script>
+    <script type="module" crossorigin src="/assets/index-Bwbh2Xl0.js"></script>
     <link rel="stylesheet" crossorigin href="/assets/index-5iqyiYFJ.css">
   </head>
   <body>

+ 26 - 0
portal/docs/conf/conf.d/front.conf

@@ -39,5 +39,31 @@ server{
         proxy_send_timeout      18000;
         client_max_body_size 10200M;
     }
+    location /mcp {
+        proxy_pass http://gdt-auto-in-svc; # 替换为你的 MCP 服务地址
+
+        # 1. 禁用响应缓冲 (这是最关键的一步)
+        proxy_buffering off;
+        proxy_cache off;
+
+        # 2. 设置 HTTP 版本和连接头
+        # SSE 需要 HTTP/1.1,并清除 Connection 头以防止被中途关闭
+        proxy_http_version 1.1;
+        proxy_set_header Connection "";
+
+        # 3. 延长超时时间
+        # MCP 连接通常是长连接,防止 NGINX 在 60 秒内关闭“闲置”连接
+        proxy_read_timeout 86400s;
+        proxy_send_timeout 86400s;
+
+        # 4. 禁用分块传输编码的潜在干扰 (可选,视客户端而定)
+        chunked_transfer_encoding off;
+
+        # 5. 透传必要的头部 (增强兼容性)
+        proxy_set_header Host $host;
+        proxy_set_header X-Real-IP $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header Accept "text/event-stream";
+    }
     error_page  405     =200 $uri;
 }

+ 1 - 1
portal/src/router/index.js

@@ -39,7 +39,7 @@ const routes = [
         path: 'ad-plan-conf/detail',
         name: 'AdPlanConfDetail',
         component: () => import('@/views/ad-plan-conf/detail.vue'),
-        meta: { title: '广告计划配置详情', icon: 'Document', hideInMenu: true }
+        meta: { title: '广告计划配置详情', icon: 'Document', hideInMenu: true, noCache: true }
       },
       {
         path: 'ad-auto-conf',

+ 4 - 7
src/main/java/com/moka/gdtauto/controller/AdPlanConfController.java

@@ -7,8 +7,6 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
-import org.springaicommunity.mcp.annotation.McpTool;
-import org.springaicommunity.mcp.annotation.McpToolParam;
 import org.springframework.beans.BeanUtils;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.web.bind.annotation.DeleteMapping;
@@ -103,7 +101,7 @@ public class AdPlanConfController {
     }
 
     @PostMapping("/gdtSuspendByPlanIds/{confId}")
-    public Result<Void> gdtSuspendByPlanIds(@PathVariable Long confId, @RequestBody Long planIds) {
+    public Result<Void> gdtSuspendByPlanIds(@PathVariable Long confId, @RequestBody List<Long> planIds) {
         if (planIds == null) {
             return Result.success("请选择要暂停广告");
         }
@@ -144,7 +142,7 @@ public class AdPlanConfController {
     }
 
     @PostMapping("/gdtDeleteByPlanIds/{confId}")
-    public Result<Void> gdtDeleteByPlanIds(@PathVariable Long confId, @RequestBody Long planIds) {
+    public Result<Void> gdtDeleteByPlanIds(@PathVariable Long confId, @RequestBody  List<Long> planIds) {
         if (planIds == null) {
             return Result.success("请选择要暂停广告");
         }
@@ -657,10 +655,9 @@ public class AdPlanConfController {
      * 获取用户的广告计划配置列表(分页)
      */
     @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,
+             @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+             @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10") Integer pageSize,
             @AuthUser SysUser sysUser) {
         try {
             Page<AdPlanConf> page = adPlanConfService.getUserAdPlanConfs(

+ 6 - 11
src/main/java/com/moka/gdtauto/controller/AdPlanController.java

@@ -1,20 +1,22 @@
 package com.moka.gdtauto.controller;
 
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.moka.gdtauto.common.Constant;
 import com.moka.gdtauto.common.Result;
 import com.moka.gdtauto.entity.AdPlan;
 import com.moka.gdtauto.service.AdPlanService;
+
 import io.swagger.v3.oas.annotations.Operation;
 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.*;
-
 /**
  * 广告计划管理控制器
  * 
@@ -34,26 +36,19 @@ 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 = "账户ID,可选", required = false)
             @Parameter(description = "广告ID,可选", example = "123456")
             @RequestParam(required = false) Long adgroupId,
-            @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 {

+ 105 - 0
src/main/java/com/moka/gdtauto/controller/McpController.java

@@ -0,0 +1,105 @@
+package com.moka.gdtauto.controller;
+
+import java.util.List;
+
+import org.springaicommunity.mcp.annotation.McpTool;
+import org.springaicommunity.mcp.annotation.McpToolParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.moka.gdtauto.common.Constant;
+import com.moka.gdtauto.common.Result;
+import com.moka.gdtauto.entity.AdPlan;
+import com.moka.gdtauto.entity.AdPlanConf;
+import com.moka.gdtauto.service.AdPlanConfService;
+import com.moka.gdtauto.service.AdPlanService;
+
+@Component
+@RequestMapping("/mcp")
+public class McpController {
+    @Autowired
+    private AdPlanService adPlanService;
+    @Autowired
+    private AdPlanConfService adPlanConfService;
+
+    @McpTool(name = "get-adgrop", description = """
+        根据广告ID获取广告信息
+        响应success=true表示获取成功
+        注意:响应[bidAmount,dailyBudget,cost,conversionsCost,scanFollowUserCost,reqIncomeVal1,repIncomeVal1]这写字段单位是分,需转化为元;
+        字段说明:bidAmount出价、dailyBudget每日预算、cost消耗、conversionsCost转化消耗、scanFollowUserCost进粉消耗、reqIncomeVal1 广告播放口径的首日广告变现金额、repIncomeVal1 转化回传口径首日广告变现金额
+        configuredStatus广告配置状态:AD_STATUS_NORMAL=有效; AD_STATUS_SUSPEND=暂停
+    """)
+    public Result<AdPlan> getAdGroup(
+            @McpToolParam(description = "广告ID", required = true) Long adgroupId) {
+        AdPlan plan = adPlanService.lambdaQuery()
+                .eq(AdPlan::getAdgroupId, adgroupId)
+                .one();
+        if (plan != null) {
+            plan.setSystemStatus(Constant.getAdGroupStatusValue(plan.getSystemStatus()));
+            return Result.success(plan);
+        } else {
+            return Result.fail("广告组不存在");
+        }
+    }
+
+    @McpTool(name = "update-adgroup-daily-budget", description = "更新广告组每日预算;响应success=true表示操作成功")
+    public Result<AdPlan> updateAdgroupDailyBudget(
+            @McpToolParam(description = "广告组ID", required = true) Long adgroupId,
+            @McpToolParam(description = "每日预算(元)", required = true) Long dailyBudgetYuan) {
+        AdPlan plan = adPlanService.lambdaQuery().eq(AdPlan::getAdgroupId, adgroupId).one();
+        if (plan != null) {
+            Long adPlanConfId = plan.getAdPlanConfId();
+            AdPlanConf adPlanConf = adPlanConfService.getOne(new LambdaQueryWrapper<AdPlanConf>()
+                    .eq(AdPlanConf::getId, adPlanConfId)
+                    .eq(AdPlanConf::getDeleted, 0));
+            try {
+                adPlanService.updateAdgroupDailyBudget(adPlanConf, plan, dailyBudgetYuan * 100);
+            } catch (Exception e) {
+                return Result.fail("更新广告组每日预算失败 e=" +  e.getMessage());
+            }
+            return Result.success();
+        } else {
+            return Result.fail("广告组不存在");
+        }
+    }
+
+    @McpTool(name = "suspend-adgroup", description = "暂停广告组;响应success=true表示操作成功")
+    public Result<AdPlan> suspendAdgroup(
+            @McpToolParam(description = "广告组ID", required = true) Long adgroupId) {
+        AdPlan plan = adPlanService.lambdaQuery().eq(AdPlan::getAdgroupId, adgroupId).one();
+        if (plan != null) {
+            Long adPlanConfId = plan.getAdPlanConfId();
+            AdPlanConf adPlanConf = adPlanConfService.getOne(new LambdaQueryWrapper<AdPlanConf>()
+                    .eq(AdPlanConf::getId, adPlanConfId)
+                    .eq(AdPlanConf::getDeleted, 0));
+            try {
+                adPlanConfService.gdtSuspendByPlans(adPlanConf, List.of(plan));
+            } catch (Exception e) {
+                return Result.fail("暂停广告组失败 e=" +  e.getMessage());
+            }
+            return Result.success();
+        }
+        return Result.fail("广告组不存在");
+    }
+
+    @McpTool(name = "delete-adgroup", description = "删除广告组;响应success=true表示操作成功")
+    public Result<AdPlan> deleteAdgroup(
+            @McpToolParam(description = "广告组ID", required = true) Long adgroupId) {
+        AdPlan plan = adPlanService.lambdaQuery().eq(AdPlan::getAdgroupId, adgroupId).one();
+        if (plan != null) {
+            Long adPlanConfId = plan.getAdPlanConfId();
+            AdPlanConf adPlanConf = adPlanConfService.getOne(new LambdaQueryWrapper<AdPlanConf>()
+                    .eq(AdPlanConf::getId, adPlanConfId)
+                    .eq(AdPlanConf::getDeleted, 0));
+            try {
+                adPlanConfService.gdtDeleteByPlanIds(adPlanConf, List.of(plan.getId()));
+            } catch (Exception e) {
+                return Result.fail("删除广告组失败 e=" +  e.getMessage());
+            }
+            return Result.success(plan);
+        }
+        return Result.fail("广告组不存在");
+    }
+}

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

@@ -1,7 +1,5 @@
 package com.moka.gdtauto.controller;
 
-import org.springaicommunity.mcp.annotation.McpTool;
-import org.springaicommunity.mcp.annotation.McpToolParam;
 import org.springframework.ai.tool.annotation.ToolParam;
 import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -43,17 +41,13 @@ 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:品牌形象)")
@@ -84,25 +78,16 @@ 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,
-            @McpToolParam(description = "排序字段", required = false)
             @Parameter(description = "排序字段(如: normalCnt, deniedCnt)") @RequestParam(required = false) String sortField,
-            @McpToolParam(description = "排序方式", required = false)
             @Parameter(description = "排序方式(ascending/descending)") @RequestParam(required = false) String sortOrder) {
         try {
             Page<OssFile> result = ossFileService.listFiles(page, size, fileType, businessType, fileName, userId, sortField, sortOrder);

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

@@ -4,8 +4,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.springaicommunity.mcp.annotation.McpTool;
-import org.springaicommunity.mcp.annotation.McpToolParam;
 import org.springframework.util.DigestUtils;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -78,16 +76,10 @@ 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 {
@@ -165,10 +157,6 @@ public class SysUserController {
         summary = "获取当前登录用户信息",
         description = "通过 @AuthUser 注解自动获取当前登录用户,无需传递参数"
     )
-    @McpTool(
-        name = "get-current-user",
-        description = "登录后获取当前登录用户信息"
-    )
     @GetMapping("/current")
     public Result<Map<String, Object>> getCurrentUser(@AuthUser SysUser currentUser) {
         try {

+ 8 - 6
src/main/java/com/moka/gdtauto/interceptor/LoginTokenInterceptor.java

@@ -1,15 +1,16 @@
 package com.moka.gdtauto.interceptor;
 
-import com.moka.gdtauto.entity.SysUser;
-import com.moka.gdtauto.service.SysUserService;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
+import org.springframework.util.AntPathMatcher;
 import org.springframework.web.servlet.HandlerInterceptor;
 
+import com.moka.gdtauto.entity.SysUser;
+import com.moka.gdtauto.service.SysUserService;
+
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
-import org.springframework.util.AntPathMatcher;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 
 
 /**
@@ -30,7 +31,8 @@ public class LoginTokenInterceptor implements HandlerInterceptor {
         "/api/user/login", 
         "/api/user/user-token-callback",
         "/api/gdt/auth/callback", 
-        "/health"
+        "/health",
+        "/mcp/**"
     };
 
     @Override

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

@@ -7,9 +7,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.moka.gdtauto.entity.AdPlan;
 import com.moka.gdtauto.entity.AdPlanConf;
 import com.moka.gdtauto.entity.AdPlanCreative;
-import com.tencent.ads.v3.TencentAds;
-
-import jakarta.validation.constraints.NotNull;
 
 /**
  * 广告计划配置服务接口
@@ -69,8 +66,8 @@ public interface AdPlanConfService extends IService<AdPlanConf> {
     void asyncReGeneratePlan(Long id);
     void gdtDeleteByConf(AdPlanConf conf);
     void gdtSuspendByConf(AdPlanConf conf);
-    void gdtDeleteByPlanIds(AdPlanConf conf, Long planIds);
-    void gdtSuspendByPlanIds(AdPlanConf conf, Long planIds);
+    void gdtDeleteByPlanIds(AdPlanConf conf, List<Long> planIds);
+    void gdtSuspendByPlanIds(AdPlanConf conf, List<Long> planIds);
     void gdtSuspendByPlans(AdPlanConf conf, List<AdPlan> plans);
     void gdtSuspendByCreatives(AdPlanConf conf, List<AdPlanCreative> creatives);
 }

+ 59 - 49
src/main/java/com/moka/gdtauto/service/impl/AdPlanConfServiceImpl.java

@@ -1,69 +1,79 @@
 package com.moka.gdtauto.service.impl;
 
-import com.alibaba.fastjson2.JSON;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.moka.gdtauto.controller.AssetDramaSyncConfController;
-import com.moka.gdtauto.entity.AdPlanConf;
-import com.moka.gdtauto.mapper.AdPlanConfMapper;
-import com.moka.gdtauto.service.AdPlanConfService;
-import com.moka.gdtauto.service.AdPlanCreativeService;
-import com.moka.gdtauto.service.TencentAdsAdgroupService;
-import com.moka.gdtauto.service.TencentAssetService;
-import com.moka.gdtauto.service.TencentAssetService.BrandUploadResult;
-import com.moka.gdtauto.service.TencentAssetService.VideoUploadResult;
-import com.moka.gdtauto.service.TencentAccountService;
-import com.moka.gdtauto.client.TencentAdsApiClientFactory;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.time.LocalDateTime;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.*;
-import java.util.stream.Collectors;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Objects;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.alibaba.fastjson2.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.moka.gdtauto.client.TencentAdsApiClientFactory;
+import com.moka.gdtauto.common.AdPlanStatus;
+import com.moka.gdtauto.common.Constant;
 import com.moka.gdtauto.entity.AdPlan;
+import com.moka.gdtauto.entity.AdPlanConf;
 import com.moka.gdtauto.entity.AdPlanCreative;
 import com.moka.gdtauto.entity.OssFile;
-import com.moka.gdtauto.entity.TencentAccountIdImage;
 import com.moka.gdtauto.entity.TencentAccountIdBrandImage;
-import com.moka.gdtauto.entity.TencentAccountIdVideoId;
+import com.moka.gdtauto.mapper.AdPlanConfMapper;
+import com.moka.gdtauto.service.AdPlanConfService;
+import com.moka.gdtauto.service.AdPlanCreativeService;
 import com.moka.gdtauto.service.AdPlanService;
 import com.moka.gdtauto.service.TencentAccountIdBrandImageService;
 import com.moka.gdtauto.service.TencentAccountIdImageService;
 import com.moka.gdtauto.service.TencentAccountIdVideoIdService;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Async;
-
-import com.tencent.ads.exception.TencentAdsResponseException;
-import com.tencent.ads.model.v3.*;
-import com.tencent.ads.v3.TencentAds;
+import com.moka.gdtauto.service.TencentAdsAdgroupService;
+import com.moka.gdtauto.service.TencentAssetService;
 import com.moka.gdtauto.util.AdgroupsAddReqPool;
 import com.moka.gdtauto.util.StrUtil;
-import com.moka.gdtauto.common.AdPlanStatus;
+import com.tencent.ads.exception.TencentAdsResponseException;
+import com.tencent.ads.model.v3.ActionButtonComponent;
+import com.tencent.ads.model.v3.ActionButtonStruct;
+import com.tencent.ads.model.v3.AdgroupsAddRequest;
+import com.tencent.ads.model.v3.AdgroupsAddResponseData;
+import com.tencent.ads.model.v3.AdgroupsDeleteRequest;
+import com.tencent.ads.model.v3.AdgroupsUpdateRequest;
+import com.tencent.ads.model.v3.BrandComponent;
+import com.tencent.ads.model.v3.BrandStruct;
+import com.tencent.ads.model.v3.ConfiguredStatus;
+import com.tencent.ads.model.v3.CreativeComponents;
+import com.tencent.ads.model.v3.DeliveryMode;
+import com.tencent.ads.model.v3.DescriptionComponent;
+import com.tencent.ads.model.v3.DescriptionStruct;
+import com.tencent.ads.model.v3.DynamicCreativeType;
+import com.tencent.ads.model.v3.DynamicCreativesAddRequest;
+import com.tencent.ads.model.v3.DynamicCreativesAddResponseData;
+import com.tencent.ads.model.v3.DynamicCreativesDeleteRequest;
+import com.tencent.ads.model.v3.DynamicCreativesUpdateRequest;
+import com.tencent.ads.model.v3.ImageComponent;
+import com.tencent.ads.model.v3.ImageStruct;
+import com.tencent.ads.model.v3.JumpinfoComponent;
+import com.tencent.ads.model.v3.JumpinfoStruct;
+import com.tencent.ads.model.v3.PageSpec;
+import com.tencent.ads.model.v3.PageType;
+import com.tencent.ads.model.v3.SmartTargetingMode;
+import com.tencent.ads.model.v3.TitleComponent;
+import com.tencent.ads.model.v3.TitleStruct;
+import com.tencent.ads.model.v3.VideoComponent;
+import com.tencent.ads.model.v3.VideoStruct;
+import com.tencent.ads.model.v3.XjPageSpec;
+import com.tencent.ads.v3.TencentAds;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.nio.file.Files;
-import java.security.MessageDigest;
-import java.util.Base64;
-import com.moka.gdtauto.common.Constant;
+import lombok.extern.slf4j.Slf4j;
 
 /**
  * 广告计划配置服务实现类
@@ -200,7 +210,7 @@ public class AdPlanConfServiceImpl extends ServiceImpl<AdPlanConfMapper, AdPlanC
 
     @Async
     @Override
-    public void gdtDeleteByPlanIds(AdPlanConf conf, Long planIds) {
+    public void gdtDeleteByPlanIds(AdPlanConf conf, List<Long> planIds) {
         log.info("gdtDeleteByPlanIds {}", conf.getId());
         try {
             TencentAds tencentAds = clientFactory.getTencentAds(conf.getJobNumber(), Constant.MAIN_ORG_ACCOUNT_ID);
@@ -346,7 +356,7 @@ public class AdPlanConfServiceImpl extends ServiceImpl<AdPlanConfMapper, AdPlanC
 
     @Async
     @Override
-    public void gdtSuspendByPlanIds(AdPlanConf conf, Long planIds) {
+    public void gdtSuspendByPlanIds(AdPlanConf conf, List<Long> planIds) {
         try {
             TencentAds tencentAds = clientFactory.getTencentAds(conf.getJobNumber(), Constant.MAIN_ORG_ACCOUNT_ID);
             List<AdPlan> plans = adPlanService.lambdaQuery()

+ 0 - 2
src/main/java/com/moka/gdtauto/service/impl/AdPlanServiceImpl.java

@@ -43,8 +43,6 @@ public class AdPlanServiceImpl extends ServiceImpl<AdPlanMapper, AdPlan> impleme
     private final AdPlanMapper adPlanMapper;
     private final TencentAdsApiClientFactory clientFactory;
 
-   
-
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long createAdPlan(AdPlan adPlan) {

+ 1 - 1
src/main/resources/application.yml

@@ -12,7 +12,7 @@ spring:
   ai:
     mcp:
       server:
-        enabled: false
+        enabled: true
         name: "腾讯快速投放"
         version: "2.0.0"
         sse-endpoint: /mcp/sse

Некоторые файлы не были показаны из-за большого количества измененных файлов