Просмотр исходного кода

fix:同步日报日报填充0值

pudongliang 4 месяцев назад
Родитель
Сommit
87dfadb94d
36 измененных файлов с 139 добавлено и 69 удалено
  1. 1 1
      portal/dist/assets/accountGroup-m56sQDEF.js
  2. 1 1
      portal/dist/assets/adAutoConf-DzLWg-RZ.js
  3. 1 1
      portal/dist/assets/adPlanConf-m4iaNP9O.js
  4. 1 1
      portal/dist/assets/auth-BHJoRLvv.js
  5. 1 1
      portal/dist/assets/conversion-C3YryWGn.js
  6. 0 0
      portal/dist/assets/detail-BRpIie4g.js
  7. 0 0
      portal/dist/assets/detail-BfNRq6Be.js
  8. 1 1
      portal/dist/assets/drama-Br7t0i_b.js
  9. 0 0
      portal/dist/assets/edit-G-D4_Jk_.js
  10. 0 0
      portal/dist/assets/index-AuR5hepX.js
  11. 0 0
      portal/dist/assets/index-B6dhgpO8.js
  12. 1 1
      portal/dist/assets/index-BRRcaIyg.js
  13. 0 0
      portal/dist/assets/index-BiwUjJ4C.js
  14. 0 0
      portal/dist/assets/index-CAbEnBkG.js
  15. 0 0
      portal/dist/assets/index-CBwV3Wre.js
  16. 0 0
      portal/dist/assets/index-CQ1slbzy.js
  17. 0 0
      portal/dist/assets/index-CUtfxf3e.js
  18. 0 0
      portal/dist/assets/index-CirT_J1L.js
  19. 0 0
      portal/dist/assets/index-CjcwTm3l.js
  20. 0 0
      portal/dist/assets/index-DATPsOL4.js
  21. 0 0
      portal/dist/assets/index-DIevDYQs.js
  22. 0 0
      portal/dist/assets/index-DTfqj6hX.js
  23. 0 0
      portal/dist/assets/index-DuEUd8jh.js
  24. 0 0
      portal/dist/assets/index-xaHPJHVZ.js
  25. 1 1
      portal/dist/assets/loadPageConf-woWRv-PC.js
  26. 1 1
      portal/dist/assets/ossFile-DOF_3m_L.js
  27. 0 0
      portal/dist/assets/request-BoOZFIOM.js
  28. 1 1
      portal/dist/assets/user-CFPXa6PO.js
  29. 1 1
      portal/dist/index.html
  30. 68 10
      portal/src/views/ad-plan-conf/detail.vue
  31. 1 0
      src/main/java/com/moka/gdtauto/client/TencentAdsApiClientFactory.java
  32. 4 1
      src/main/java/com/moka/gdtauto/controller/AdPlanController.java
  33. 48 43
      src/main/java/com/moka/gdtauto/service/AdPlanDailyReportService.java
  34. 1 1
      src/main/java/com/moka/gdtauto/service/AdPlanService.java
  35. 4 1
      src/main/java/com/moka/gdtauto/service/impl/AdPlanServiceImpl.java
  36. 2 2
      src/test/java/com/moka/gdtauto/service/AdPlanConfAsyncTest.java

+ 1 - 1
portal/dist/assets/accountGroup-CC1adQS4.js → portal/dist/assets/accountGroup-m56sQDEF.js

@@ -1 +1 @@
-import{r as u}from"./request-2CyynisS.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-BoOZFIOM.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-DC1ZhFrQ.js → portal/dist/assets/adAutoConf-DzLWg-RZ.js

@@ -1 +1 @@
-import{r as e}from"./request-2CyynisS.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-BoOZFIOM.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-B_Atl4vP.js → portal/dist/assets/adPlanConf-m4iaNP9O.js

@@ -1 +1 @@
-import{r as a}from"./request-2CyynisS.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-BoOZFIOM.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-CK4bunUz.js → portal/dist/assets/auth-BHJoRLvv.js

@@ -1 +1 @@
-import{r as t}from"./request-2CyynisS.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-BoOZFIOM.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-BS06mk4P.js → portal/dist/assets/conversion-C3YryWGn.js

@@ -1 +1 @@
-import{r as t}from"./request-2CyynisS.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-BoOZFIOM.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-BRpIie4g.js


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


+ 1 - 1
portal/dist/assets/drama-dSaPpJa-.js → portal/dist/assets/drama-Br7t0i_b.js

@@ -1 +1 @@
-import{r as t}from"./request-2CyynisS.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-BoOZFIOM.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-G-D4_Jk_.js


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


+ 1 - 1
portal/dist/assets/loadPageConf-DkMgu9F5.js → portal/dist/assets/loadPageConf-woWRv-PC.js

@@ -1 +1 @@
-import{r as o}from"./request-2CyynisS.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-BoOZFIOM.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-aTlflaDN.js → portal/dist/assets/ossFile-DOF_3m_L.js

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


+ 1 - 1
portal/dist/assets/user-zDESo9RD.js → portal/dist/assets/user-CFPXa6PO.js

@@ -1 +1 @@
-import{r as e}from"./request-2CyynisS.js";function s(){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})}export{u as a,s as b,a as c,n as g,o as l};
+import{r as e}from"./request-BoOZFIOM.js";function s(){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})}export{u as a,s as b,a as c,n as g,o as l};

+ 1 - 1
portal/dist/index.html

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

+ 68 - 10
portal/src/views/ad-plan-conf/detail.vue

@@ -215,7 +215,12 @@
           placeholder="按账户ID筛选" 
           placeholder="按账户ID筛选" 
           clearable
           clearable
           style="width: 200px"
           style="width: 200px"
-          @change="fetchAdPlans"
+        />
+        <el-input 
+          v-model="queryParams.adgroupId" 
+          placeholder="按广告ID筛选" 
+          clearable
+          style="width: 200px"
         />
         />
         <el-select 
         <el-select 
           v-model="queryParams.status" 
           v-model="queryParams.status" 
@@ -229,6 +234,11 @@
           <el-option label="失败" :value="3" />
           <el-option label="失败" :value="3" />
           <el-option label="已提交" :value="4" />
           <el-option label="已提交" :value="4" />
         </el-select>
         </el-select>
+        <el-button type="primary" @click="fetchAdPlans">
+              <el-icon><Search /></el-icon>
+              查询
+            </el-button>
+            <el-button @click="handleReset">重置</el-button>
       </div>
       </div>
 
 
       <!-- 广告计划表格 -->
       <!-- 广告计划表格 -->
@@ -256,13 +266,13 @@
               >
               >
                 <el-table-column prop="creativeName" label="创意名称" min-width="100" show-overflow-tooltip />
                 <el-table-column prop="creativeName" label="创意名称" min-width="100" show-overflow-tooltip />
                 <el-table-column prop="creativeId" label="腾讯创意ID" width="130">
                 <el-table-column prop="creativeId" label="腾讯创意ID" width="130">
-                  <template #default="{ row: creative }">
-                    <el-button
-                      v-if="creative.creativeId"
-                      type="primary"
-                      link
-                      @click="router.push({ path: '/daily-report', query: { dynamicCreativeId: creative.creativeId } })"
-                    >{{ creative.creativeId }}</el-button>
+                  <template #default="{ row }">
+                    {{ row.creativeId }}
+                    <el-button v-if="row.creativeId > 0" link size="small" @click="goToTencentByAdgroupId(row)">
+                     <el-icon color="#409efc" class="no-inherit">
+                      <Share />
+                    </el-icon>
+                    </el-button>
                     <span v-else>-</span>
                     <span v-else>-</span>
                   </template>
                   </template>
                 </el-table-column>
                 </el-table-column>
@@ -332,8 +342,28 @@
           </template>
           </template>
         </el-table-column>
         </el-table-column>
         <el-table-column prop="adgroupName" label="广告组名称" min-width="100" show-overflow-tooltip />
         <el-table-column prop="adgroupName" label="广告组名称" min-width="100" show-overflow-tooltip />
-        <el-table-column prop="accountId" label="账户ID" width="120" />
-        <el-table-column prop="adgroupId" label="广告ID" width="130" />
+        <el-table-column prop="accountId" label="账户ID" width="130" >
+          <template #default="{ row }">
+            {{ row.accountId }}
+            <el-button v-if="row.accountId > 0" size="small"  link  @click="goToTencentByAccountId(row)">
+               <el-icon color="#409efc" class="no-inherit">
+                <Share />
+              </el-icon>
+              </el-button>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="adgroupId" label="广告ID" width="150" >
+          <template #default="{ row }">
+            {{ row.adgroupId }}
+            <el-button v-if="row.adgroupId > 0" size="small" link @click="goToTencentByAdgroupId(row)">
+              <el-icon color="#409efc" class="no-inherit">
+                <Share />
+              </el-icon>
+            </el-button>
+            <span v-else>-</span>
+          </template>
+          </el-table-column>
         <el-table-column label="广告类型" width="100">
         <el-table-column label="广告类型" width="100">
           <template #default="{ row }">
           <template #default="{ row }">
             <el-tag :type="getAdTypeColor(row.adType)" size="small">
             <el-tag :type="getAdTypeColor(row.adType)" size="small">
@@ -437,6 +467,7 @@ import {
     deleteByPlanIds,
     deleteByPlanIds,
   suspendByPlanIds
   suspendByPlanIds
 } from '@/api/adPlanConf'
 } from '@/api/adPlanConf'
+import dayjs from 'dayjs'
 
 
 const route = useRoute()
 const route = useRoute()
 const router = useRouter()
 const router = useRouter()
@@ -456,6 +487,7 @@ const selectedRows = ref([])
 // 查询参数
 // 查询参数
 const queryParams = ref({
 const queryParams = ref({
   confId: route.query.id,
   confId: route.query.id,
+  adgroupId: null,
   accountId: null,
   accountId: null,
   status: null,
   status: null,
   pageNum: 1,
   pageNum: 1,
@@ -504,6 +536,32 @@ const fetchConfDetail = async () => {
   }
   }
 }
 }
 
 
+const goToTencentByAccountId  = (row) => {
+  const date = dayjs().format('YYYY-MM-DD')
+  window.open(`https://ad.qq.com/atlas/${row.accountId}/admanage/index?start_date=${date}&end_date=${date}&tab=adgroup&query={%22operation_status%22:[%22CALCULATE_STATUS_EXCLUDE_DEL%22],%22system_status%22:[]}`, '_blank')
+}
+
+const goToTencentByAdgroupId = (row) => {
+  const date = dayjs().format('YYYY-MM-DD')
+  window.open(`https://ad.qq.com/atlas/${row.accountId}/admanage/index?start_date=${date}&end_date=${date}&tab=adgroup&query={%22operation_status%22:[%22CALCULATE_STATUS_EXCLUDE_DEL%22],%22system_status%22:[],%22search_name%22:%22${row.adgroupId}%22}`, '_blank')
+}
+
+const gotToTencentCreative = (row) => {
+  window.open(`https://ad.qq.com/atlas/${row.accountId}/admanage/index?tab=dynamic_creative&adgroupid=${row.adgroupId}&accountid=${row.accountId}&query={%22operation_status%22:[%22CALCULATE_STATUS_EXCLUDE_DEL%22],%22created_time%22:-29}`, '_blank')
+}
+
+const handleReset = () => {
+  queryParams.value = {
+    confId: route.query.id,
+    adgroupId: null,
+    accountId: null,
+    status: null,
+    pageNum: 1,
+    pageSize: 10
+  }
+  fetchAdPlans()
+}
+
 // 获取广告计划列表
 // 获取广告计划列表
 const fetchAdPlans = async () => {
 const fetchAdPlans = async () => {
   planLoading.value = true
   planLoading.value = true

+ 1 - 0
src/main/java/com/moka/gdtauto/client/TencentAdsApiClientFactory.java

@@ -37,6 +37,7 @@ public class TencentAdsApiClientFactory {
      * @throws Exception 当获取token失败时抛出
      * @throws Exception 当获取token失败时抛出
      */
      */
     public TencentAds getTencentAds(String jobNumber, Long orgAccountId) throws Exception {
     public TencentAds getTencentAds(String jobNumber, Long orgAccountId) throws Exception {
+       
         // 获取账户的访问令牌
         // 获取账户的访问令牌
         TencentAdsAuth auth = authService.getByJobNumberAndAccountId(jobNumber, orgAccountId);
         TencentAdsAuth auth = authService.getByJobNumberAndAccountId(jobNumber, orgAccountId);
         if (auth == null) {
         if (auth == null) {

+ 4 - 1
src/main/java/com/moka/gdtauto/controller/AdPlanController.java

@@ -44,6 +44,9 @@ public class AdPlanController {
             @McpToolParam(description = "账户ID,可选", required = false)
             @McpToolParam(description = "账户ID,可选", required = false)
             @Parameter(description = "账户ID,可选", example = "123456")
             @Parameter(description = "账户ID,可选", example = "123456")
             @RequestParam(required = false) Long accountId,
             @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)
             @McpToolParam(description = "状态,可选:1-待执行,2-执行中,3-失败,4-已结束", required = false)
             @Parameter(description = "状态,可选:1-待执行,2-执行中,3-失败,4-已结束", example = "1")
             @Parameter(description = "状态,可选:1-待执行,2-执行中,3-失败,4-已结束", example = "1")
             @RequestParam(required = false) Integer status,
             @RequestParam(required = false) Integer status,
@@ -54,7 +57,7 @@ public class AdPlanController {
             @Parameter(description = "每页大小", example = "10")
             @Parameter(description = "每页大小", example = "10")
             @RequestParam(defaultValue = "10") Integer pageSize) {
             @RequestParam(defaultValue = "10") Integer pageSize) {
         try {
         try {
-            Page<AdPlan> page = adPlanService.getAdPlans(confId,accountId, status, pageNum, pageSize);
+            Page<AdPlan> page = adPlanService.getAdPlans(confId,accountId,adgroupId, status, pageNum, pageSize);
             page.getRecords().forEach(r -> {
             page.getRecords().forEach(r -> {
                 r.setSystemStatus(Constant.getAdGroupStatusValue(r.getSystemStatus()));
                 r.setSystemStatus(Constant.getAdGroupStatusValue(r.getSystemStatus()));
             });
             });

+ 48 - 43
src/main/java/com/moka/gdtauto/service/AdPlanDailyReportService.java

@@ -150,7 +150,6 @@ public class AdPlanDailyReportService {
         String jobNumber = conf.getJobNumber();
         String jobNumber = conf.getJobNumber();
         TencentAds tencentAds = clientFactory.getTencentAds(jobNumber, Constant.MAIN_ORG_ACCOUNT_ID);
         TencentAds tencentAds = clientFactory.getTencentAds(jobNumber, Constant.MAIN_ORG_ACCOUNT_ID);
 
 
-        // 日期范围使用 conf.createTime 的日期
         String startStr = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
         String startStr = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
         String endStr = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
         String endStr = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
         ReportDateRange dateRange = new ReportDateRange();
         ReportDateRange dateRange = new ReportDateRange();
@@ -249,64 +248,70 @@ public class AdPlanDailyReportService {
                 null   // modularDetailMode
                 null   // modularDetailMode
         );
         );
 
 
-        if (response == null || response.getList() == null || response.getList().isEmpty()) {
+        if (response == null) {
             log.warn("[syncBatch] accountId={} 未返回日报数据", accountId);
             log.warn("[syncBatch] accountId={} 未返回日报数据", accountId);
             return 0;
             return 0;
         }
         }
 
 
         // 构建更新数据
         // 构建更新数据
         List<AdPlan> toUpdate = new ArrayList<>();
         List<AdPlan> toUpdate = new ArrayList<>();
-        for (ReportStruct rs : response.getList()) {
-            if (rs.getAdgroupId() == null) {
-                continue;
-            }
-            AdPlan update = new AdPlan();
-            update.setAdgroupId(rs.getAdgroupId());
-
-            if (isReqTime) {
-                // REQUEST_TIME 口径:更新 cost, view_count, valid_click_count, ctr, conversions_cost, req_income_val_1, req_income_roi_1
-                update.setCost(rs.getCost());
-                update.setViewCount(rs.getViewCount());
-                update.setValidClickCount(rs.getValidClickCount());
-                update.setCtr(d2b(rs.getCtr()));
-                update.setConversionsCost(rs.getConversionsCost());
-                update.setReqIncomeVal1(rs.getIncomeVal1());
-                update.setReqIncomeRoi1(d2b(rs.getIncomeRoi1()));
-                update.setScanFollowUserCost(rs.getScanFollowUserCost());
-            } else {
-                // REPORTING_TIME 口径:更新 rep_income_val_1, rep_income_roi_1
-                update.setRepIncomeVal1(rs.getIncomeVal1());
-                update.setRepIncomeRoi1(d2b(rs.getIncomeRoi1()));
-            }
-            update.setUpdateTime(LocalDateTime.now());
-            toUpdate.add(update);
+        if (response.getList() != null) {
+            for (ReportStruct rs : response.getList()) {
+                if (rs.getAdgroupId() == null) {
+                    continue;
+                }
+                AdPlan update = new AdPlan();
+                update.setAdgroupId(rs.getAdgroupId());
+
+                if (isReqTime) {
+                    // REQUEST_TIME 口径:更新 cost, view_count, valid_click_count, ctr, conversions_cost, req_income_val_1, req_income_roi_1
+                    update.setCost(rs.getCost());
+                    update.setViewCount(rs.getViewCount());
+                    update.setValidClickCount(rs.getValidClickCount());
+                    update.setCtr(d2b(rs.getCtr()));
+                    update.setConversionsCost(rs.getConversionsCost());
+                    update.setReqIncomeVal1(rs.getIncomeVal1());
+                    update.setReqIncomeRoi1(d2b(rs.getIncomeRoi1()));
+                    update.setScanFollowUserCost(rs.getScanFollowUserCost());
+                } else {
+                    // REPORTING_TIME 口径:更新 rep_income_val_1, rep_income_roi_1
+                    update.setRepIncomeVal1(rs.getIncomeVal1());
+                    update.setRepIncomeRoi1(d2b(rs.getIncomeRoi1()));
+                }
+                update.setUpdateTime(LocalDateTime.now());
+                toUpdate.add(update);
+            }   
         }
         }
 
 
-        if (toUpdate.isEmpty()) {
-            return 0;
-        }
-        Map<Long, AdPlan> updateMap = toUpdate.stream().collect(Collectors.toMap(AdPlan::getId, p -> p));
+        //无报表数据的,填充0值
+        Map<Long, AdPlan> updateMap = toUpdate.stream().collect(Collectors.toMap(AdPlan::getAdgroupId, p -> p));
         batch.forEach(p -> {
         batch.forEach(p -> {
-            if (!updateMap.containsKey(p.getId())) {
-                AdPlan update = updateMap.get(p.getId());
+            if (!updateMap.containsKey(p.getAdgroupId())) {
+                AdPlan update = new AdPlan();
+                update.setAdgroupId(p.getAdgroupId());
+
                 if (isReqTime) { 
                 if (isReqTime) { 
-                    p.setCost(0L);
-                    p.setViewCount(0L);
-                    p.setValidClickCount(0L);
-                    p.setCtr(BigDecimal.ZERO);
-                    p.setConversionsCost(0L);
-                    p.setReqIncomeVal1(0L);
-                    p.setReqIncomeRoi1(BigDecimal.ZERO);
-                    p.setScanFollowUserCost(0L);
+                    update.setCost(0L);
+                    update.setViewCount(0L);
+                    update.setValidClickCount(0L);
+                    update.setCtr(BigDecimal.ZERO);
+                    update.setConversionsCost(0L);
+                    update.setReqIncomeVal1(0L);
+                    update.setReqIncomeRoi1(BigDecimal.ZERO);
+                    update.setScanFollowUserCost(0L);
                 } else {
                 } else {
-                    p.setRepIncomeVal1(0L);
-                    p.setRepIncomeRoi1(BigDecimal.ZERO);
+                    update.setRepIncomeVal1(0L);
+                    update.setRepIncomeRoi1(BigDecimal.ZERO);
                 }
                 }
-                p.setUpdateTime(LocalDateTime.now());
+                update.setUpdateTime(LocalDateTime.now());
                 toUpdate.add(update);
                 toUpdate.add(update);
             }
             }
         });
         });
 
 
+        if (toUpdate.isEmpty()) {
+            return 0;
+        }
+
         // 批量更新
         // 批量更新
         if (isReqTime) {
         if (isReqTime) {
             adPlanMapper.batchUpdateReqDailyReport(toUpdate);
             adPlanMapper.batchUpdateReqDailyReport(toUpdate);

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

@@ -47,7 +47,7 @@ public interface AdPlanService extends IService<AdPlan> {
      * @param pageSize 每页大小
      * @param pageSize 每页大小
      * @return 计划分页列表
      * @return 计划分页列表
      */
      */
-    Page<AdPlan> getAdPlans(Long confId, Long accountId, Integer status, Integer pageNum, Integer pageSize);
+    Page<AdPlan> getAdPlans(Long confId, Long accountId, Long adgroupId, Integer status, Integer pageNum, Integer pageSize);
 
 
     /**
     /**
      * 获取广告计划详情
      * 获取广告计划详情

+ 4 - 1
src/main/java/com/moka/gdtauto/service/impl/AdPlanServiceImpl.java

@@ -91,7 +91,7 @@ public class AdPlanServiceImpl extends ServiceImpl<AdPlanMapper, AdPlan> impleme
     }
     }
 
 
     @Override
     @Override
-    public Page<AdPlan> getAdPlans(Long confId, Long accountId, Integer status, Integer pageNum, Integer pageSize) {
+    public Page<AdPlan> getAdPlans(Long confId, Long accountId, Long adgroupId, Integer status, Integer pageNum, Integer pageSize) {
         Page<AdPlan> page = new Page<>(pageNum, pageSize);
         Page<AdPlan> page = new Page<>(pageNum, pageSize);
         
         
         LambdaQueryWrapper<AdPlan> queryWrapper = new LambdaQueryWrapper<>();
         LambdaQueryWrapper<AdPlan> queryWrapper = new LambdaQueryWrapper<>();
@@ -103,6 +103,9 @@ public class AdPlanServiceImpl extends ServiceImpl<AdPlanMapper, AdPlan> impleme
         if (accountId != null) {
         if (accountId != null) {
             queryWrapper.eq(AdPlan::getAccountId, accountId);
             queryWrapper.eq(AdPlan::getAccountId, accountId);
         }
         }
+        if (adgroupId != null) {
+            queryWrapper.eq(AdPlan::getAdgroupId, adgroupId);
+        }
         if (status != null) {
         if (status != null) {
             queryWrapper.eq(AdPlan::getStatus, status);
             queryWrapper.eq(AdPlan::getStatus, status);
         }
         }

+ 2 - 2
src/test/java/com/moka/gdtauto/service/AdPlanConfAsyncTest.java

@@ -66,7 +66,7 @@ class AdPlanConfAsyncTest {
 
 
         // 2. 查询该配置下的所有 AdPlan
         // 2. 查询该配置下的所有 AdPlan
         List<AdPlan> plans = adPlanService.getAdPlans(
         List<AdPlan> plans = adPlanService.getAdPlans(
-            TEST_CONF_ID, null, null, 1, 100
+            TEST_CONF_ID, null, null, 1, 1, 100
         ).getRecords();
         ).getRecords();
         
         
         if (plans == null || plans.isEmpty()) {
         if (plans == null || plans.isEmpty()) {
@@ -196,7 +196,7 @@ class AdPlanConfAsyncTest {
 
 
         // 查询计划
         // 查询计划
         List<AdPlan> plans = adPlanService.getAdPlans(
         List<AdPlan> plans = adPlanService.getAdPlans(
-            TEST_CONF_ID, null, null, 1, 100
+            TEST_CONF_ID, null, null,1, 1, 100
         ).getRecords();
         ).getRecords();
 
 
         System.out.println("📊 找到 " + plans.size() + " 个广告计划:");
         System.out.println("📊 找到 " + plans.size() + " 个广告计划:");

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