pudongliang 4 месяцев назад
Родитель
Сommit
b8f34bbd99
52 измененных файлов с 204 добавлено и 122 удалено
  1. 1 1
      portal/dist/assets/accountGroup-2OvOnCg-.js
  2. 1 1
      portal/dist/assets/adAutoConf-CpVJ1VSG.js
  3. 1 1
      portal/dist/assets/adPlanConf-C-V5pcFH.js
  4. 1 1
      portal/dist/assets/auth-DxAtOt9T.js
  5. 1 1
      portal/dist/assets/conversion-nqk9Ow0a.js
  6. 0 0
      portal/dist/assets/detail-BMUR8xJq.js
  7. 1 1
      portal/dist/assets/drama-CFOfZF5N.js
  8. 0 0
      portal/dist/assets/edit-CR1R9d7f.js
  9. 0 0
      portal/dist/assets/index-B3hIu6mW.js
  10. 0 0
      portal/dist/assets/index-B4JE8xf4.js
  11. 0 1
      portal/dist/assets/index-B_-QlG0U.css
  12. 0 0
      portal/dist/assets/index-BbZhaLoC.js
  13. 0 0
      portal/dist/assets/index-CcfekgJo.js
  14. 0 0
      portal/dist/assets/index-CiHLDthm.js
  15. 0 0
      portal/dist/assets/index-CkX32DmJ.js
  16. 0 0
      portal/dist/assets/index-Cm0stliE.js
  17. 0 0
      portal/dist/assets/index-Co7EfRsG.js
  18. 0 0
      portal/dist/assets/index-CpTFWUsY.js
  19. 0 0
      portal/dist/assets/index-D1vx8K8-.js
  20. 0 0
      portal/dist/assets/index-DFf4DEC5.js
  21. 0 0
      portal/dist/assets/index-Dv8hNIv3.js
  22. 0 0
      portal/dist/assets/index-JFktROtA.js
  23. 0 0
      portal/dist/assets/index-Ust3SDug.js
  24. 1 0
      portal/dist/assets/index-cmer5d5F.css
  25. 0 0
      portal/dist/assets/index-epvLJnJ-.js
  26. 0 0
      portal/dist/assets/index-gxutLLv-.js
  27. 0 0
      portal/dist/assets/index-iu-2Nzj4.js
  28. 0 0
      portal/dist/assets/index-qlIRce_Z.js
  29. 0 0
      portal/dist/assets/index-rse884Nk.js
  30. 1 1
      portal/dist/assets/index-sSt_Bee6.js
  31. 0 0
      portal/dist/assets/index-t54aOB64.js
  32. 0 0
      portal/dist/assets/index-x-66BCRm.js
  33. 1 1
      portal/dist/assets/loadPageConf-CAQ9FTkb.js
  34. 1 1
      portal/dist/assets/ossFile-CfVewPzV.js
  35. 0 0
      portal/dist/assets/request-CgdhMl9O.js
  36. 1 1
      portal/dist/assets/user-Czh6CS-e.js
  37. 1 1
      portal/dist/index.html
  38. 0 1
      portal/src/router/index.js
  39. 9 0
      portal/src/views/login/index.vue
  40. 24 4
      portal/src/views/oss-file/index.vue
  41. 19 9
      src/main/java/com/moka/gdtauto/controller/OssFileController.java
  42. 11 2
      src/main/java/com/moka/gdtauto/entity/OssFile.java
  43. 5 4
      src/main/java/com/moka/gdtauto/mapper/AdPlanCreativeMapper.java
  44. 3 2
      src/main/java/com/moka/gdtauto/service/AdPlanCreativeService.java
  45. 5 2
      src/main/java/com/moka/gdtauto/service/OssFileService.java
  46. 26 22
      src/main/java/com/moka/gdtauto/service/impl/AdPlanCreativeServiceImpl.java
  47. 16 15
      src/main/java/com/moka/gdtauto/service/impl/AdPlanServiceImpl.java
  48. 33 23
      src/main/java/com/moka/gdtauto/service/impl/OssFileServiceImpl.java
  49. 0 24
      src/main/java/com/moka/gdtauto/task/ExampleTask.java
  50. 2 2
      src/main/java/com/moka/gdtauto/task/SyncAdgroupSystemStatusTask.java
  51. 13 0
      src/main/resources/mapper/AdPlanCreativeMapper.xml
  52. 26 0
      src/test/java/com/moka/gdtauto/service/SyncAdgroupSystemStatusTaskTest.java

+ 1 - 1
portal/dist/assets/accountGroup-C0V-RvXi.js → portal/dist/assets/accountGroup-2OvOnCg-.js

@@ -1 +1 @@
-import{r as u}from"./request-CJOT2p1f.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-CgdhMl9O.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-Dl39a7n8.js → portal/dist/assets/adAutoConf-CpVJ1VSG.js

@@ -1 +1 @@
-import{r as e}from"./request-CJOT2p1f.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-CgdhMl9O.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-BwIZJJ3f.js → portal/dist/assets/adPlanConf-C-V5pcFH.js

@@ -1 +1 @@
-import{r as a}from"./request-CJOT2p1f.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-CgdhMl9O.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-EsBVgL4h.js → portal/dist/assets/auth-DxAtOt9T.js

@@ -1 +1 @@
-import{r as t}from"./request-CJOT2p1f.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-CgdhMl9O.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-BFR0pe9E.js → portal/dist/assets/conversion-nqk9Ow0a.js

@@ -1 +1 @@
-import{r as t}from"./request-CJOT2p1f.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-CgdhMl9O.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-BMUR8xJq.js


+ 1 - 1
portal/dist/assets/drama-dq_EyCP1.js → portal/dist/assets/drama-CFOfZF5N.js

@@ -1 +1 @@
-import{r as t}from"./request-CJOT2p1f.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-CgdhMl9O.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-CR1R9d7f.js


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


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


+ 0 - 1
portal/dist/assets/index-B_-QlG0U.css

@@ -1 +0,0 @@
-.btn-primary[data-v-273a3de8]{background:linear-gradient(135deg,#667eea,#764ba2);border:none;color:#fff}.btn-primary[data-v-273a3de8]:hover{background:linear-gradient(135deg,#764ba2,#667eea)}.btn-secondary[data-v-273a3de8]{border-color:#e5e7eb;color:#6b7280}.btn-secondary[data-v-273a3de8]:hover{background-color:#f9fafb}[data-v-273a3de8] .el-upload-dragger{border:2px dashed #d1d5db;border-radius:8px;background-color:#f9fafb;transition:all .3s}[data-v-273a3de8] .el-upload-dragger:hover{border-color:#667eea;background-color:#f3f4f6}

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


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


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


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


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


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


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


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


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


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


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


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


+ 1 - 0
portal/dist/assets/index-cmer5d5F.css

@@ -0,0 +1 @@
+.btn-primary[data-v-68b802a8]{background:linear-gradient(135deg,#667eea,#764ba2);border:none;color:#fff}.btn-primary[data-v-68b802a8]:hover{background:linear-gradient(135deg,#764ba2,#667eea)}.btn-secondary[data-v-68b802a8]{border-color:#e5e7eb;color:#6b7280}.btn-secondary[data-v-68b802a8]:hover{background-color:#f9fafb}[data-v-68b802a8] .el-upload-dragger{border:2px dashed #d1d5db;border-radius:8px;background-color:#f9fafb;transition:all .3s}[data-v-68b802a8] .el-upload-dragger:hover{border-color:#667eea;background-color:#f3f4f6}

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


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


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


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


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


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


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


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


+ 1 - 1
portal/dist/assets/loadPageConf-BWMxCPXo.js → portal/dist/assets/loadPageConf-CAQ9FTkb.js

@@ -1 +1 @@
-import{r as o}from"./request-CJOT2p1f.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-CgdhMl9O.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-CO6YXkdy.js → portal/dist/assets/ossFile-CfVewPzV.js

@@ -1 +1 @@
-import{r as t}from"./request-CJOT2p1f.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-CgdhMl9O.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-CgdhMl9O.js


+ 1 - 1
portal/dist/assets/user-DAhWUiuy.js → portal/dist/assets/user-Czh6CS-e.js

@@ -1 +1 @@
-import{r as e}from"./request-CJOT2p1f.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-CgdhMl9O.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-DftAq06U.js"></script>
+    <script type="module" crossorigin src="/assets/index-sSt_Bee6.js"></script>
     <link rel="stylesheet" crossorigin href="/assets/index-5iqyiYFJ.css">
   </head>
   <body>

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

@@ -168,7 +168,6 @@ router.beforeEach((to, from, next) => {
     next('/login')
   } else {
     const userInfo = JSON.parse(storeUserInfo)
-    console.log('userInfo:', userInfo)
     if (userInfo.userTokenExpiresAt && dayjs(userInfo.userTokenExpiresAt).isBefore(dayjs())) {
       // 第三方平台实名认证已过期,强制跳转个人中心重新认证
       // 若目标已是 /profile,直接放行,避免无限重定向

+ 9 - 0
portal/src/views/login/index.vue

@@ -67,6 +67,8 @@ defineOptions({
 })
 
 import { ref, reactive } from 'vue'
+import { onMounted } from 'vue'
+
 import { useRouter } from 'vue-router'
 import { ElMessage } from 'element-plus'
 import { login } from '@/api/user'
@@ -93,6 +95,13 @@ const loginRules = {
 const loginFormRef = ref(null)
 const loading = ref(false)
 
+onMounted(() => {
+   if (import.meta.env.MODE === 'development') {
+     loginForm.jobNumber = '12458'
+     loginForm.password = '123qwe!@#'
+   }
+})
+
 // 登录处理
 const handleLogin = async () => {
   if (!loginFormRef.value) return

+ 24 - 4
portal/src/views/oss-file/index.vue

@@ -123,13 +123,13 @@
       <el-table 
         :data="fileList" 
         v-loading="loading"
-        @selection-change="handleSelectionChange"
+        @sort-change="handleSortChange"
         style="width: 100%"
         :header-cell-style="{ background: '#f9fafb', color: '#374151', fontWeight: '600' }">
-        <el-table-column type="selection" width="55"></el-table-column>
-        
         <el-table-column prop="id" label="ID" width="80"></el-table-column>
         <el-table-column prop="assetId" label="资产ID" width="120"></el-table-column>
+        <el-table-column prop="normalCnt" label="审核通过数" width="120" sortable="custom"></el-table-column>
+        <el-table-column prop="deniedCnt" label="审核拒绝数" width="120" sortable="custom"></el-table-column>
         <el-table-column prop="businessType" label="业务分类" width="120">
           <template #default="{ row }">
             <el-tag :type="row.businessType === 1 ? 'primary' : 'success'" size="small">
@@ -327,6 +327,12 @@ const pagination = reactive({
   total: 0
 })
 
+// 排序
+const sortParams = reactive({
+  sortField: '',
+  sortOrder: ''
+})
+
 // 预览
 const previewVisible = ref(false)
 const previewUrl = ref('')
@@ -464,7 +470,9 @@ const loadFileList = async () => {
       size: pagination.size,
       fileType: queryForm.fileType,
       businessType: queryForm.businessType,
-      fileName: queryForm.fileName
+      fileName: queryForm.fileName,
+      sortField: sortParams.sortField,
+      sortOrder: sortParams.sortOrder
     })
     if (res.success) {
       fileList.value = res.data.records
@@ -480,6 +488,18 @@ const loadFileList = async () => {
   }
 }
 
+// 排序变化
+const handleSortChange = ({ prop, order }) => {
+  if (order) {
+    sortParams.sortField = prop
+    sortParams.sortOrder = order
+  } else {
+    sortParams.sortField = ''
+    sortParams.sortOrder = ''
+  }
+  loadFileList()
+}
+
 // 查询
 const handleQuery = () => {
   pagination.page = 1

+ 19 - 9
src/main/java/com/moka/gdtauto/controller/OssFileController.java

@@ -1,24 +1,30 @@
 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;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.moka.gdtauto.annotation.AuthUser;
 import com.moka.gdtauto.common.Result;
 import com.moka.gdtauto.entity.OssFile;
 import com.moka.gdtauto.entity.SysUser;
 import com.moka.gdtauto.service.OssFileService;
+
 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.ai.tool.annotation.Tool;
-import org.springframework.ai.tool.annotation.ToolParam;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
 /**
  * OSS文件管理Controller
  *
@@ -93,9 +99,13 @@ public class OssFileController {
             @McpToolParam(description = "文件名(模糊查询)", required = false)
             @Parameter(description = "文件名(模糊查询)") @RequestParam(required = false) String fileName,
             @McpToolParam(description = "创建人id", required = false)
-            @Parameter(description = "创建人id") @RequestParam(required = false) Long userId) {
+            @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);
+            Page<OssFile> result = ossFileService.listFiles(page, size, fileType, businessType, fileName, userId, sortField, sortOrder);
             return Result.success(result);
         } catch (Exception e) {
             log.error("查询文件列表失败", e);

+ 11 - 2
src/main/java/com/moka/gdtauto/entity/OssFile.java

@@ -1,11 +1,12 @@
 package com.moka.gdtauto.entity;
 
+import java.time.LocalDateTime;
+
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
 
-import java.time.LocalDateTime;
+import lombok.Data;
 
 /**
  * OSS文件管理实体类
@@ -54,6 +55,14 @@ public class OssFile {
     private String fileUrl;
 
     private String fileMd5;
+    /**
+     * 审核通过数
+     */
+    private Integer normalCnt;
+    /**
+     * 审核拒绝数
+     */
+    private Integer deniedCnt;
 
     /**
      * OSS对象Key

+ 5 - 4
src/main/java/com/moka/gdtauto/mapper/AdPlanCreativeMapper.java

@@ -1,14 +1,13 @@
 package com.moka.gdtauto.mapper;
 
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.moka.gdtauto.entity.AdPlan;
-import com.moka.gdtauto.entity.AdPlanCreative;
-
 import java.util.List;
 
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.moka.gdtauto.entity.AdPlanCreative;
+
 /**
  * 广告计划创意Mapper接口
  * 
@@ -33,4 +32,6 @@ public interface AdPlanCreativeMapper extends BaseMapper<AdPlanCreative> {
      * @param plans 包含 adgroupId 和日报字段的广告计划列表
      */
     void batchUpdateRepDailyReport(@Param("creatives") List<AdPlanCreative> plans);
+
+    void md5ApprovalCount();
 }

+ 3 - 2
src/main/java/com/moka/gdtauto/service/AdPlanCreativeService.java

@@ -1,11 +1,11 @@
 package com.moka.gdtauto.service;
 
+import java.util.List;
+
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.moka.gdtauto.entity.AdPlanCreative;
 
-import java.util.List;
-
 /**
  * 广告计划创意服务接口
  * 
@@ -76,4 +76,5 @@ public interface AdPlanCreativeService extends IService<AdPlanCreative> {
     List<AdPlanCreative> getCreativesByConfId(Long confId);
 
     void syncAdPlanCreativeStatus(Long confId);
+    void adPlanCreativeStatus(Long confId);
 }

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

@@ -1,9 +1,10 @@
 package com.moka.gdtauto.service;
 
+import org.springframework.web.multipart.MultipartFile;
+
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.moka.gdtauto.entity.OssFile;
-import org.springframework.web.multipart.MultipartFile;
 
 /**
  * OSS文件Service接口
@@ -51,7 +52,9 @@ public interface OssFileService extends IService<OssFile> {
      * @param businessType 业务分类
      * @param fileName 文件名(模糊查询)
      * @param userId 创建人id
+     * @param sortField 排序字段
+     * @param sortOrder 排序方式
      * @return 分页结果
      */
-    Page<OssFile> listFiles(Long page, Long size, String fileType, Integer businessType, String fileName, Long userId);
+    Page<OssFile> listFiles(Long page, Long size, String fileType, Integer businessType, String fileName, Long userId, String sortField, String sortOrder);
 }

+ 26 - 22
src/main/java/com/moka/gdtauto/service/impl/AdPlanCreativeServiceImpl.java

@@ -1,34 +1,31 @@
 package com.moka.gdtauto.service.impl;
 
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
 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.Constant;
-import com.moka.gdtauto.entity.AdPlan;
 import com.moka.gdtauto.entity.AdPlanCreative;
 import com.moka.gdtauto.mapper.AdPlanCreativeMapper;
 import com.moka.gdtauto.service.AdPlanCreativeService;
 import com.moka.gdtauto.service.AdPlanService;
-import com.tencent.ads.model.v3.AdgroupsGetResponseData;
 import com.tencent.ads.model.v3.DynamicCreativesGetResponseData;
 import com.tencent.ads.model.v3.FilterOperator;
 import com.tencent.ads.model.v3.FilteringStruct;
 import com.tencent.ads.v3.TencentAds;
 
-import lombok.extern.slf4j.Slf4j;
-
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Service;
 import lombok.AllArgsConstructor;
-
-import org.springframework.transaction.annotation.Transactional;
-
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
+import lombok.extern.slf4j.Slf4j;
 
 /**
  * 广告计划创意服务实现类
@@ -162,15 +159,16 @@ public class AdPlanCreativeServiceImpl extends ServiceImpl<AdPlanCreativeMapper,
                 .orderByAsc(AdPlanCreative::getId));
     }
 
-    @Async
     @Override
-    public void syncAdPlanCreativeStatus(Long confId) {
+    public void adPlanCreativeStatus(Long confId) {
         final int PAGE_SIZE = 500;
         final int BATCH_LIMIT = 100; // 腾讯广告 adgroup_id IN 最大 100
 
         log.info("[定时任务] 开始同步广告创意 system_status");
         int totalUpdated = 0;
         try {
+            // 获取 TencentAds 实例(使用主 orgAccountId)
+            TencentAds tencentAds = clientFactory.getTencentAds(null, Constant.MAIN_ORG_ACCOUNT_ID);
             int pageNum = 1;
             while (true) {
                 // 1. 分页查询 status=4 的广告创意,ID 降序
@@ -202,7 +200,7 @@ public class AdPlanCreativeServiceImpl extends ServiceImpl<AdPlanCreativeMapper,
                         List<AdPlanCreative> batch = plansOfAccount.subList(fromIdx, toIdx);
 
                         try {
-                            int updated = syncBatch(accountId, batch);
+                            int updated = syncBatch(tencentAds, accountId, batch);
                             totalUpdated += updated;
                         } catch (Exception e) {
                             log.error("[定时任务] 同步 accountId={} 的广告状态失败,batch index={}", accountId, i, e);
@@ -221,10 +219,18 @@ public class AdPlanCreativeServiceImpl extends ServiceImpl<AdPlanCreativeMapper,
         }
 
         log.info("[定时任务] 同步广告创意 system_status 完成,共更新 {} 条", totalUpdated);
-    
+        // 统计素材情况
+
+        adPlanCreativeMapper.md5ApprovalCount();
+    }
+
+    @Async
+    @Override
+    public void syncAdPlanCreativeStatus(Long confId) {
+        adPlanCreativeStatus(confId);
     }
 
-    private int syncBatch(Long accountId, List<AdPlanCreative> batch) throws Exception {
+    private int syncBatch(TencentAds tencentAds, Long accountId, List<AdPlanCreative> batch) throws Exception {
         final int BATCH_LIMIT = 100; // 腾讯广告 adgroup_id IN 最大 100
         final List<String> FIELDS = List.of("adgroup_id", "dynamic_creative_id", "configured_status", "creative_set_approval_status", "is_deleted");
 
@@ -241,9 +247,7 @@ public class AdPlanCreativeServiceImpl extends ServiceImpl<AdPlanCreativeMapper,
         List<FilteringStruct> filtering = new ArrayList<>();
         filtering.add(filter);
 
-        // 获取 TencentAds 实例(使用主 orgAccountId)
-        TencentAds tencentAds = clientFactory.getTencentAds(null, Constant.MAIN_ORG_ACCOUNT_ID);
-
+        
         DynamicCreativesGetResponseData response = tencentAds.dynamicCreatives().dynamicCreativesGet(
                 accountId,
                 filtering,

+ 16 - 15
src/main/java/com/moka/gdtauto/service/impl/AdPlanServiceImpl.java

@@ -1,5 +1,15 @@
 package com.moka.gdtauto.service.impl;
 
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -10,8 +20,8 @@ import com.moka.gdtauto.entity.AdPlanConf;
 import com.moka.gdtauto.mapper.AdPlanMapper;
 import com.moka.gdtauto.service.AdPlanService;
 import com.moka.gdtauto.util.StrUtil;
-import com.tencent.ads.model.v3.AdgroupsUpdateRequest;
 import com.tencent.ads.model.v3.AdgroupsGetResponseData;
+import com.tencent.ads.model.v3.AdgroupsUpdateRequest;
 import com.tencent.ads.model.v3.FilterOperator;
 import com.tencent.ads.model.v3.FilteringStruct;
 import com.tencent.ads.model.v3.SmartTargetingMode;
@@ -20,16 +30,6 @@ import com.tencent.ads.v3.TencentAds;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
 /**
  * 广告计划服务实现类
  * 
@@ -146,7 +146,9 @@ public class AdPlanServiceImpl extends ServiceImpl<AdPlanMapper, AdPlan> impleme
 
         log.info("[定时任务] 开始同步广告计划 system_status");
         int totalUpdated = 0;
+        // 获取 TencentAds 实例(使用主 orgAccountId)
         try {
+            TencentAds tencentAds = clientFactory.getTencentAds(null, Constant.MAIN_ORG_ACCOUNT_ID);
             int pageNum = 1;
             while (true) {
                 // 1. 分页查询 status=4 的广告计划,ID 降序
@@ -178,7 +180,7 @@ public class AdPlanServiceImpl extends ServiceImpl<AdPlanMapper, AdPlan> impleme
                         List<AdPlan> batch = plansOfAccount.subList(fromIdx, toIdx);
 
                         try {
-                            int updated = syncBatch(accountId, batch);
+                            int updated = syncBatch(tencentAds, accountId, batch);
                             totalUpdated += updated;
                         } catch (Exception e) {
                             log.error("[定时任务] 同步 accountId={} 的广告状态失败,batch index={}", accountId, i, e);
@@ -206,7 +208,7 @@ public class AdPlanServiceImpl extends ServiceImpl<AdPlanMapper, AdPlan> impleme
      * @param batch     该账户下的广告计划列表(不超过 100 条)
      * @return 实际更新条数
      */
-    private int syncBatch(Long accountId, List<AdPlan> batch) throws Exception {
+    private int syncBatch(TencentAds tencentAds, Long accountId, List<AdPlan> batch) throws Exception {
         final int BATCH_LIMIT = 100; // 腾讯广告 adgroup_id IN 最大 100
         final List<String> FIELDS = List.of("adgroup_id", "created_time", "configured_status", "system_status", "is_deleted");
 
@@ -223,8 +225,7 @@ public class AdPlanServiceImpl extends ServiceImpl<AdPlanMapper, AdPlan> impleme
         List<FilteringStruct> filtering = new ArrayList<>();
         filtering.add(filter);
 
-        // 获取 TencentAds 实例(使用主 orgAccountId)
-        TencentAds tencentAds = clientFactory.getTencentAds(null, Constant.MAIN_ORG_ACCOUNT_ID);
+
 
         AdgroupsGetResponseData response = tencentAds.adgroups().adgroupsGet(
                 accountId,

+ 33 - 23
src/main/java/com/moka/gdtauto/service/impl/OssFileServiceImpl.java

@@ -1,37 +1,23 @@
 package com.moka.gdtauto.service.impl;
 
-import com.aliyun.oss.common.utils.BinaryUtil;
+import java.time.LocalDateTime;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
 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.Constant;
-import com.moka.gdtauto.controller.OssFileController;
 import com.moka.gdtauto.entity.OssFile;
 import com.moka.gdtauto.mapper.OssFileMapper;
 import com.moka.gdtauto.service.OssFileService;
 import com.moka.gdtauto.service.TencentAssetService;
 import com.moka.gdtauto.util.OssUtil;
 import com.moka.gdtauto.util.TencentFileMd5Util;
-import com.tencent.ads.model.v3.ImagesAddResponseData;
-import com.tencent.ads.model.v3.VideosAddResponseData;
-import com.tencent.ads.v3.TencentAds;
 
 import lombok.AllArgsConstructor;
-import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.time.LocalDateTime;
-import java.util.Base64;
 
 /**
  * OSS文件Service实现类
@@ -146,7 +132,7 @@ public class OssFileServiceImpl extends ServiceImpl<OssFileMapper, OssFile> impl
     }
 
     @Override
-    public Page<OssFile> listFiles(Long page, Long size, String fileType, Integer businessType, String fileName, Long userId) {
+    public Page<OssFile> listFiles(Long page, Long size, String fileType, Integer businessType, String fileName, Long userId, String sortField, String sortOrder) {
         Page<OssFile> pageParam = new Page<>(page, size);
         LambdaQueryWrapper<OssFile> wrapper = new LambdaQueryWrapper<>();
         
@@ -170,8 +156,32 @@ public class OssFileServiceImpl extends ServiceImpl<OssFileMapper, OssFile> impl
             wrapper.eq(OssFile::getCreatedBy, userId);
         }
         
-        // 按创建时间倒序
-        wrapper.orderByDesc(OssFile::getCreatedTime);
+        // 排序逻辑
+        if (sortField != null && !sortField.trim().isEmpty()) {
+            boolean isAsc = "ascending".equalsIgnoreCase(sortOrder);
+            switch (sortField) {
+                case "normalCnt":
+                    if (isAsc) {
+                        wrapper.orderByAsc(OssFile::getNormalCnt);
+                    } else {
+                        wrapper.orderByDesc(OssFile::getNormalCnt);
+                    }
+                    break;
+                case "deniedCnt":
+                    if (isAsc) {
+                        wrapper.orderByAsc(OssFile::getDeniedCnt);
+                    } else {
+                        wrapper.orderByDesc(OssFile::getDeniedCnt);
+                    }
+                    break;
+                default:
+                    // 默认按创建时间倒序
+                    wrapper.orderByDesc(OssFile::getCreatedTime);
+            }
+        } else {
+            // 没有指定排序时,按创建时间倒序
+            wrapper.orderByDesc(OssFile::getCreatedTime);
+        }
         
         return page(pageParam, wrapper);
     }

+ 0 - 24
src/main/java/com/moka/gdtauto/task/ExampleTask.java

@@ -1,24 +0,0 @@
-package com.moka.gdtauto.task;
-
-import lombok.extern.slf4j.Slf4j;
-import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-
-/**
- * 示例定时任务
- */
-@Slf4j
-@Component
-public class ExampleTask {
-
-    /**
-     * 每5分钟执行一次
-     */
-    @Scheduled(cron = "0 */5 * * * ?")
-    @SchedulerLock(name = "exampleTask", lockAtMostFor = "4m", lockAtLeastFor = "1m")
-    public void execute() {
-        log.info("示例定时任务执行");
-        // TODO: 实现定时任务逻辑
-    }
-}

+ 2 - 2
src/main/java/com/moka/gdtauto/task/SyncAdgroupSystemStatusTask.java

@@ -37,7 +37,7 @@ public class SyncAdgroupSystemStatusTask {
     @Scheduled(cron = "0 0 * * * *")
     @SchedulerLock(name = "syncAdgroupSystemStatus", lockAtMostFor = "9m", lockAtLeastFor = "1m")
     public void syncAdgroupSystemStatus() {
-        adPlanService.syncAdPlanStatus(11L);
+        adPlanService.syncAdPlanStatus(null);
     }
 
     /**
@@ -46,7 +46,7 @@ public class SyncAdgroupSystemStatusTask {
     @Scheduled(cron = "0 0 * * * *")
     @SchedulerLock(name = "syncAdgroupCreativeStatus", lockAtMostFor = "9m", lockAtLeastFor = "1m")
     public void syncAdgroupCreativeStatus() {
-        adPlanCreativeService.syncAdPlanCreativeStatus(11L);
+        adPlanCreativeService.syncAdPlanCreativeStatus(null);
     }
 
 }

+ 13 - 0
src/main/resources/mapper/AdPlanCreativeMapper.xml

@@ -41,4 +41,17 @@
         </foreach>
     </update>
 
+    <!-- md5ApprovalCount --> 
+
+    <update id="md5ApprovalCount">
+         update oss_file f inner join (
+                select creative_file_md5, approval_status,
+                sum(case when approval_status = 'CREATIVE_SET_APPROVAL_STATUS_NORMAL' then 1 else 0 end)  as nomarl_cnt,
+                sum(case when approval_status = 'CREATIVE_SET_APPROVAL_STATUS_DENIED' then 1 else 0 end) as denied_cnt
+                from ad_plan_creative
+                where creative_file_md5 is not null and approval_status != ''
+                group by creative_file_md5, approval_status ) t 
+        set f.normal_cnt = t.nomarl_cnt, f.denied_cnt = t.denied_cnt
+        where f.file_md5 = t.creative_file_md5
+    </update>
 </mapper>

+ 26 - 0
src/test/java/com/moka/gdtauto/service/SyncAdgroupSystemStatusTaskTest.java

@@ -0,0 +1,26 @@
+package com.moka.gdtauto.service;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+
+import com.moka.gdtauto.GdtAutoApplication;
+
+/**
+ * @author 
+ * mvn test -Dtest=SyncAdgroupSystemStatusTaskTest#testSyncAdPlanCreativeStatus -Dspring.profiles.active=test
+ */
+@SpringBootTest(classes = GdtAutoApplication.class)
+@ActiveProfiles("test")
+public class SyncAdgroupSystemStatusTaskTest {
+
+    @Autowired
+    private AdPlanCreativeService adPlanCreativeService;
+
+
+    @Test
+    public void testSyncAdPlanCreativeStatus() {
+        adPlanCreativeService.adPlanCreativeStatus(null);
+    }
+}

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