Browse Source

feat:创意日报avgROI

pudongliang 3 months ago
parent
commit
8a5335fbcd
42 changed files with 214 additions and 144 deletions
  1. 1 1
      portal/dist/assets/accountGroup-CWAxuIvv.js
  2. 1 1
      portal/dist/assets/adAutoConf-D-bFbcOZ.js
  3. 1 1
      portal/dist/assets/adPlanConf-DSXPkH7g.js
  4. 1 1
      portal/dist/assets/auth-BCEb_h3Z.js
  5. 1 1
      portal/dist/assets/conversion-CxO9m8Og.js
  6. 0 0
      portal/dist/assets/detail-H2fSeeY3.js
  7. 1 1
      portal/dist/assets/drama-DahK2MBQ.js
  8. 0 0
      portal/dist/assets/edit-BPeMWw5d.js
  9. 0 0
      portal/dist/assets/index-ApTBmTjn.js
  10. 0 0
      portal/dist/assets/index-B1b45v2S.js
  11. 0 0
      portal/dist/assets/index-B2bgV-K8.js
  12. 0 0
      portal/dist/assets/index-BQCVsMn2.js
  13. 0 0
      portal/dist/assets/index-Bmzk1pW0.js
  14. 0 0
      portal/dist/assets/index-CDE3Bfa2.js
  15. 0 0
      portal/dist/assets/index-CVe_VtlJ.js
  16. 0 0
      portal/dist/assets/index-ClDVlIeb.js
  17. 0 0
      portal/dist/assets/index-CrKg9ZKv.js
  18. 0 0
      portal/dist/assets/index-CrfqyZOQ.js
  19. 0 0
      portal/dist/assets/index-DCWRruqp.js
  20. 0 0
      portal/dist/assets/index-DRmfRXlY.js
  21. 0 0
      portal/dist/assets/index-DYiqOUmL.js
  22. 0 0
      portal/dist/assets/index-DaWwmB1h.js
  23. 0 0
      portal/dist/assets/index-Dde3-_Gk.js
  24. 0 0
      portal/dist/assets/index-DsoYxpHV.js
  25. 0 0
      portal/dist/assets/index-OpjwHZYR.js
  26. 1 1
      portal/dist/assets/index-T4ukwOTx.js
  27. 0 0
      portal/dist/assets/index-gAxE7uIr.js
  28. 0 0
      portal/dist/assets/index-yyJH-b7J.js
  29. 1 1
      portal/dist/assets/loadPageConf-z0C2QqyL.js
  30. 1 1
      portal/dist/assets/ossFile-DiVQDfjl.js
  31. 0 0
      portal/dist/assets/request-BeS3b16d.js
  32. 1 1
      portal/dist/assets/user-BqO_eG3l.js
  33. 1 1
      portal/dist/index.html
  34. 8 0
      portal/src/api/dailyCreativeReport.js
  35. 22 19
      portal/src/views/daily-adgroup-report/index.vue
  36. 73 114
      portal/src/views/daily-creative-report/index.vue
  37. 24 0
      src/main/java/com/moka/gdtauto/controller/DailyCreativeReportController.java
  38. 5 0
      src/main/java/com/moka/gdtauto/mapper/RepDailyCreativeReportMapper.java
  39. 5 0
      src/main/java/com/moka/gdtauto/mapper/ReqDailyCreativeReportMapper.java
  40. 11 0
      src/main/java/com/moka/gdtauto/service/DailyCreativeReportService.java
  41. 27 0
      src/main/resources/mapper/RepDailyCreativeReportMapper.xml
  42. 28 0
      src/main/resources/mapper/ReqDailyCreativeReportMapper.xml

+ 1 - 1
portal/dist/assets/accountGroup-v3r0H1CD.js → portal/dist/assets/accountGroup-CWAxuIvv.js

@@ -1 +1 @@
-import{r as u}from"./request-BSQsKCsT.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-BeS3b16d.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-Dj4ye5ZZ.js → portal/dist/assets/adAutoConf-D-bFbcOZ.js

@@ -1 +1 @@
-import{r as e}from"./request-BSQsKCsT.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 d(t){return e({url:`/api/ad-auto-conf/${t}`,method:"delete"})}function i(t){return e({url:`/api/ad-auto-conf/execute?id=${t}`,method:"post"})}function f(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,f as b,n as c,d,i as e,u as g,a as s,r as u};
+import{r as e}from"./request-BeS3b16d.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 d(t){return e({url:`/api/ad-auto-conf/${t}`,method:"delete"})}function i(t){return e({url:`/api/ad-auto-conf/execute?id=${t}`,method:"post"})}function f(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,f as b,n as c,d,i as e,u as g,a as s,r as u};

+ 1 - 1
portal/dist/assets/adPlanConf-D_c4iGM3.js → portal/dist/assets/adPlanConf-DSXPkH7g.js

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

+ 1 - 1
portal/dist/assets/auth-BJKslpjZ.js → portal/dist/assets/auth-BCEb_h3Z.js

@@ -1 +1 @@
-import{r as t}from"./request-BSQsKCsT.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-BeS3b16d.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-CoHryZbR.js → portal/dist/assets/conversion-CxO9m8Og.js

@@ -1 +1 @@
-import{r as t}from"./request-BSQsKCsT.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-BeS3b16d.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};

File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/detail-H2fSeeY3.js


+ 1 - 1
portal/dist/assets/drama-Biplb52o.js → portal/dist/assets/drama-DahK2MBQ.js

@@ -1 +1 @@
-import{r as t}from"./request-BSQsKCsT.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-BeS3b16d.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};

File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/edit-BPeMWw5d.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-ApTBmTjn.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-B1b45v2S.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-B2bgV-K8.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-BQCVsMn2.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-Bmzk1pW0.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-CDE3Bfa2.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-CVe_VtlJ.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-ClDVlIeb.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-CrKg9ZKv.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-CrfqyZOQ.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-DCWRruqp.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-DRmfRXlY.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-DYiqOUmL.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-DaWwmB1h.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-Dde3-_Gk.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-DsoYxpHV.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-OpjwHZYR.js


File diff suppressed because it is too large
+ 1 - 1
portal/dist/assets/index-T4ukwOTx.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-gAxE7uIr.js


File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/index-yyJH-b7J.js


+ 1 - 1
portal/dist/assets/loadPageConf-BVoPbaND.js → portal/dist/assets/loadPageConf-z0C2QqyL.js

@@ -1 +1 @@
-import{r as o}from"./request-BSQsKCsT.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-BeS3b16d.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-B1p_LnA1.js → portal/dist/assets/ossFile-DiVQDfjl.js

@@ -1 +1 @@
-import{r as t}from"./request-BSQsKCsT.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-BeS3b16d.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};

File diff suppressed because it is too large
+ 0 - 0
portal/dist/assets/request-BeS3b16d.js


+ 1 - 1
portal/dist/assets/user-BaTJcJ6w.js → portal/dist/assets/user-BqO_eG3l.js

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

+ 8 - 0
portal/src/api/dailyCreativeReport.js

@@ -17,3 +17,11 @@ export function getDailyReportList(params) {
     params
   })
 }
+
+export function getAvgROI(params) {
+  return request({
+    url: '/api/gdt/daily-creative-report/avg-roi',
+    method: 'get',
+    params
+  })
+}

+ 22 - 19
portal/src/views/daily-adgroup-report/index.vue

@@ -143,6 +143,9 @@
         <el-table-column prop="validClickCount" label="有效点击" width="110" align="right" sortable="custom">
           <template #default="{ row }">{{ formatInt(row.validClickCount) }}</template>
         </el-table-column>
+        <el-table-column prop="cpc" label="点击均价" width="90" align="right">
+          <template #default="{ row }">{{ formatNum(row.cpc / 100) }}</template>
+        </el-table-column>
         <el-table-column prop="ctr" label="点击率" width="110" align="right" sortable="custom">
           <template #default="{ row }">{{ formatPct(row.ctr) }}</template>
         </el-table-column>
@@ -155,36 +158,36 @@
         <el-table-column prop="incomeRoi1" label="1日ROI" width="110" align="right" sortable="custom">
           <template #default="{ row }">{{ formatRoi(row.incomeRoi1) }}</template>
         </el-table-column>
-        <el-table-column prop="incomeRoi3" label="3日ROI" width="110" align="right" sortable="custom">
-          <template #default="{ row }">{{ formatRoi(row.incomeRoi3) }}</template>
+        <el-table-column label="1日变现" width="100" align="right">
+          <template #default="{ row }">{{ formatNum(row.incomeVal1 / 100) }}</template>
+        </el-table-column>
+        <el-table-column label="24h ROI" width="100" align="right">
+          <template #default="{ row }">{{ formatRoi(row.incomeRoi124h) }}</template>
         </el-table-column>
-         <el-table-column prop="cpc" label="CPC" width="90" align="right">
-          <template #default="{ row }">{{ formatNum(row.cpc) }}</template>
+        <el-table-column label="24h变现" width="100" align="right">
+          <template #default="{ row }">{{ formatNum(row.incomeVal24h / 100) }}</template>
         </el-table-column>
-        <el-table-column label="1日LTV" width="100" align="right">
-          <template #default="{ row }">{{ formatNum(row.incomeVal1) }}</template>
+        <el-table-column prop="incomeRoi3" label="3日ROI" width="110" align="right" sortable="custom">
+          <template #default="{ row }">{{ formatRoi(row.incomeRoi3) }}</template>
         </el-table-column>
-        <el-table-column label="3日LTV" width="100" align="right">
-          <template #default="{ row }">{{ formatNum(row.incomeVal3) }}</template>
+         
+        
+        <el-table-column label="3日变现" width="100" align="right">
+          <template #default="{ row }">{{ formatNum(row.incomeVal3 / 100) }}</template>
         </el-table-column>
         <el-table-column label="7日ROI" width="90" align="right">
           <template #default="{ row }">{{ formatRoi(row.incomeRoi7) }}</template>
         </el-table-column>
-        <el-table-column label="7日LTV" width="100" align="right">
-          <template #default="{ row }">{{ formatNum(row.incomeVal7) }}</template>
+        <el-table-column label="7日变现" width="100" align="right">
+          <template #default="{ row }">{{ formatNum(row.incomeVal7 / 100) }}</template>
         </el-table-column>
         <el-table-column label="14日ROI" width="90" align="right">
           <template #default="{ row }">{{ formatRoi(row.incomeRoi14) }}</template>
         </el-table-column>
-        <el-table-column label="14日LTV" width="100" align="right">
-          <template #default="{ row }">{{ formatNum(row.incomeVal14) }}</template>
-        </el-table-column>
-        <el-table-column label="24h ROI" width="100" align="right">
-          <template #default="{ row }">{{ formatRoi(row.incomeRoi124h) }}</template>
-        </el-table-column>
-        <el-table-column label="24h LTV" width="100" align="right">
-          <template #default="{ row }">{{ formatNum(row.incomeVal24h) }}</template>
+        <el-table-column label="14日  " width="100" align="right">
+          <template #default="{ row }">{{ formatNum(row.incomeVal14 / 100) }}</template>
         </el-table-column>
+        
         <el-table-column prop="videoOuterPlayCount" label="视频播放" width="100" align="right">
           <template #default="{ row }">{{ formatInt(row.videoOuterPlayCount) }}</template>
         </el-table-column>
@@ -249,7 +252,7 @@ const queryForm = reactive({
 const getDefaultDateRange = () => {
   const end = new Date()
   const start = new Date()
-  start.setDate(start.getDate() - 7)
+  start.setDate(start.getDate())
   const fmt = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
   return [fmt(start), fmt(end)]
 }

+ 73 - 114
portal/src/views/daily-creative-report/index.vue

@@ -6,8 +6,10 @@
       <div class="border-b border-gray-200 pb-4 mb-6">
         <div class="flex items-center justify-between flex-wrap gap-4">
           <h2 class="text-xl font-semibold text-gray-800 flex items-center gap-2">
-            <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-blue-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
-              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
+            <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-blue-500" fill="none" viewBox="0 0 24 24"
+              stroke="currentColor">
+              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
+                d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
             </svg>
             动态创意日报表
           </h2>
@@ -54,121 +56,75 @@
               <el-radio-button value="REPORTING_TIME">上报时间</el-radio-button>
             </el-radio-group>
           </div>
-<el-select
-            v-model="queryForm.confId"
-            placeholder="配置"
-            clearable
-            filterable
-            style="width: 180px"
-            @change="handleSearch"
-          >
-            <el-option
-              v-for="g in confOptions"
-              :key="g.id"
-              :label="g.name"
-              :value="g.id"
-            />
+          <el-select v-model="queryForm.confId" placeholder="配置" clearable filterable style="width: 180px"
+            @change="handleSearch">
+            <el-option v-for="g in confOptions" :key="g.id" :label="g.name" :value="g.id" />
           </el-select>
-          <el-select
-            v-model="queryForm.groupId"
-            placeholder="账号组筛选"
-            clearable
-            filterable
-            style="width: 180px"
-            @change="handleSearch"
-          >
-            <el-option
-              v-for="g in groupOptions"
-              :key="g.id"
-              :label="g.groupName"
-              :value="g.id"
-            />
+          <el-select v-model="queryForm.groupId" placeholder="账号组筛选" clearable filterable style="width: 180px"
+            @change="handleSearch">
+            <el-option v-for="g in groupOptions" :key="g.id" :label="g.groupName" :value="g.id" />
           </el-select>
 
-          <el-input
-            v-model="queryForm.accountId"
-            placeholder="账户ID"
-            clearable
-            style="width: 160px"
-            @clear="handleSearch"
-          />
-          <el-input
-            v-model="queryForm.adgroupId"
-            placeholder="广告ID"
-            clearable
-            style="width: 180px"
-            @clear="handleSearch"
-          />
-
-          <el-input
-            v-model="queryForm.dynamicCreativeId"
-            placeholder="动态创意ID"
-            clearable
-            style="width: 180px"
-            @clear="handleSearch"
-          />
-
-          <el-date-picker
-            v-model="queryDateRange"
-            type="daterange"
-            range-separator="~"
-            start-placeholder="开始日期"
-            end-placeholder="结束日期"
-            format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD"
-            style="width: 240px"
-            @change="handleSearch"
-          />
+          <el-input v-model="queryForm.accountId" placeholder="账户ID" clearable style="width: 160px"
+            @clear="handleSearch" />
+          <el-input v-model="queryForm.adgroupId" placeholder="广告ID" clearable style="width: 180px"
+            @clear="handleSearch" />
+
+          <el-input v-model="queryForm.dynamicCreativeId" placeholder="动态创意ID" clearable style="width: 180px"
+            @clear="handleSearch" />
+
+          <el-date-picker v-model="queryDateRange" type="daterange" range-separator="~" start-placeholder="开始日期"
+            end-placeholder="结束日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width: 240px"
+            @change="handleSearch" />
         </div>
 
         <!-- 第二行:按钮右对齐 -->
         <div class="flex justify-end gap-2">
           <el-button type="primary" @click="handleSearch">
-            <el-icon><Search /></el-icon>
+            <el-icon>
+              <Search />
+            </el-icon>
             查询
           </el-button>
           <el-button @click="handleReset">重置</el-button>
         </div>
       </div>
 
+      <p>平均ROI:{{ formatRoi(avgRoi) }}</p>
+
       <!-- 数据表格 -->
-      <el-table
-        :data="reportList"
-        v-loading="loading"
-        stripe
-        border
-        style="width: 100%"
-        max-height="600"
-        :default-sort="{ prop: 'cost', order: 'descending' }"
-        @sort-change="handleSortChange"
-      >
+      <el-table :data="reportList" v-loading="loading" stripe border style="width: 100%" max-height="600"
+        :default-sort="{ prop: 'cost', order: 'descending' }" @sort-change="handleSortChange">
         <!-- yyyy-MM-dd -->
-         <el-table-column prop="confId" label="配置ID" width="110" show-overflow-tooltip>
-           <template #default="{ row }">{{ getConfName(row.confId) }}</template>
-          </el-table-column>
-         <el-table-column prop="groupId" label="账号组ID" width="110" show-overflow-tooltip >
+        <el-table-column prop="confId" label="配置ID" width="110" show-overflow-tooltip>
+          <template #default="{ row }">{{ getConfName(row.confId) }}</template>
+        </el-table-column>
+        <el-table-column prop="groupId" label="账号组ID" width="110" show-overflow-tooltip>
           <template #default="{ row }">{{ getGroupName(row.groupId) }}</template>
-          </el-table-column>
-        <el-table-column prop="date" label="日期" width="110"  sortable="custom">
+        </el-table-column>
+        <el-table-column prop="date" label="日期" width="110" sortable="custom">
           <template #default="{ row }">{{ row.date.substring(0, 10) }}</template>
         </el-table-column>
-        <el-table-column prop="accountId" label="账户ID" width="110"  >
+        <el-table-column prop="accountId" label="账户ID" width="110">
           <template #default="{ row }">
-            <el-button v-if="row.accountId > 0" type="primary" size="small" style="user-select: text;"  link  @click="goToTencentByAccountId(row)">
+            <el-button v-if="row.accountId > 0" type="primary" size="small" style="user-select: text;" link
+              @click="goToTencentByAccountId(row)">
               {{ row.accountId }}
             </el-button>
           </template>
         </el-table-column>
-        <el-table-column prop="adgroupId" label="广告ID" width="120" >
+        <el-table-column prop="adgroupId" label="广告ID" width="120">
           <template #default="{ row }">
-            <el-button v-if="row.adgroupId > 0" type="primary" size="small" style="user-select: text;"  link  @click="goToTencentByAdgroupId(row)">
+            <el-button v-if="row.adgroupId > 0" type="primary" size="small" style="user-select: text;" link
+              @click="goToTencentByAdgroupId(row)">
               {{ row.adgroupId }}
             </el-button>
           </template>
         </el-table-column>
-        <el-table-column prop="dynamicCreativeId" label="创意ID" width="120" >
+        <el-table-column prop="dynamicCreativeId" label="创意ID" width="120">
           <template #default="{ row }">
-            <el-button v-if="row.dynamicCreativeId > 0" type="primary" size="small"  style="user-select: text;" link  @click="goToTencentCreative(row)">
+            <el-button v-if="row.dynamicCreativeId > 0" type="primary" size="small" style="user-select: text;" link
+              @click="goToTencentCreative(row)">
               {{ row.dynamicCreativeId }}
             </el-button>
           </template>
@@ -183,6 +139,9 @@
         <el-table-column prop="validClickCount" label="有效点击" width="110" align="right" sortable="custom">
           <template #default="{ row }">{{ formatInt(row.validClickCount) }}</template>
         </el-table-column>
+        <el-table-column prop="cpc" label="点击均价" width="90" align="right">
+          <template #default="{ row }">{{ formatNum(row.cpc / 100) }}</template>
+        </el-table-column>
         <el-table-column prop="ctr" label="点击率" width="110" align="right" sortable="custom">
           <template #default="{ row }">{{ formatPct(row.ctr) }}</template>
         </el-table-column>
@@ -195,36 +154,33 @@
         <el-table-column prop="incomeRoi1" label="1日ROI" width="110" align="right" sortable="custom">
           <template #default="{ row }">{{ formatRoi(row.incomeRoi1) }}</template>
         </el-table-column>
-        <el-table-column prop="incomeRoi3" label="3日ROI" width="110" align="right" sortable="custom">
-          <template #default="{ row }">{{ formatRoi(row.incomeRoi3) }}</template>
-        </el-table-column>
-        <el-table-column label="1日LTV" width="100" align="right">
-          <template #default="{ row }">{{ formatNum(row.incomeVal1) }}</template>
+         <el-table-column label="1日变现" width="100" align="right">
+          <template #default="{ row }">{{ formatNum(row.incomeVal1 / 100) }}</template>
         </el-table-column>
         
-         <el-table-column prop="cpc" label="CPC" width="90" align="right">
-          <template #default="{ row }">{{ formatNum(row.cpc) }}</template>
+        <el-table-column prop="incomeRoi3" label="3日ROI" width="110" align="right" sortable="custom">
+          <template #default="{ row }">{{ formatRoi(row.incomeRoi3) }}</template>
         </el-table-column>
-        <el-table-column label="3日LTV" width="100" align="right">
-          <template #default="{ row }">{{ formatNum(row.incomeVal3) }}</template>
+        <el-table-column label="3日变现" width="100" align="right">
+          <template #default="{ row }">{{ formatNum(row.incomeVal3 / 100) }}</template>
         </el-table-column>
         <el-table-column label="7日ROI" width="90" align="right">
           <template #default="{ row }">{{ formatRoi(row.incomeRoi7) }}</template>
         </el-table-column>
-        <el-table-column label="7日LTV" width="100" align="right">
-          <template #default="{ row }">{{ formatNum(row.incomeVal7) }}</template>
+        <el-table-column label="7日变现" width="100" align="right">
+          <template #default="{ row }">{{ formatNum(row.incomeVal7 / 100) }}</template>
         </el-table-column>
         <el-table-column label="14日ROI" width="90" align="right">
           <template #default="{ row }">{{ formatRoi(row.incomeRoi14) }}</template>
         </el-table-column>
-        <el-table-column label="14日LTV" width="100" align="right">
-          <template #default="{ row }">{{ formatNum(row.incomeVal14) }}</template>
+        <el-table-column label="14日变现" width="100" align="right">
+          <template #default="{ row }">{{ formatNum(row.incomeVal14 / 100) }}</template>
         </el-table-column>
         <el-table-column label="24h ROI" width="100" align="right">
           <template #default="{ row }">{{ formatRoi(row.incomeRoi124h) }}</template>
         </el-table-column>
-        <el-table-column label="24h LTV" width="100" align="right">
-          <template #default="{ row }">{{ formatNum(row.incomeVal24h) }}</template>
+        <el-table-column label="24h变现" width="100" align="right">
+          <template #default="{ row }">{{ formatNum(row.incomeVal24h / 100) }}</template>
         </el-table-column>
         <el-table-column prop="videoOuterPlayCount" label="视频播放" width="100" align="right">
           <template #default="{ row }">{{ formatInt(row.videoOuterPlayCount) }}</template>
@@ -236,15 +192,9 @@
 
       <!-- 分页 -->
       <div class="mt-6 flex justify-end">
-        <el-pagination
-          v-model:current-page="pagination.page"
-          v-model:page-size="pagination.pageSize"
-          :page-sizes="[20, 50, 100, 200]"
-          :total="pagination.total"
-          layout="total, sizes, prev, pager, next, jumper"
-          @size-change="handleSizeChange"
-          @current-change="handleCurrentChange"
-        />
+        <el-pagination v-model:current-page="pagination.page" v-model:page-size="pagination.pageSize"
+          :page-sizes="[20, 50, 100, 200]" :total="pagination.total" layout="total, sizes, prev, pager, next, jumper"
+          @size-change="handleSizeChange" @current-change="handleCurrentChange" />
       </div>
     </div>
   </div>
@@ -259,7 +209,7 @@ import { ref, reactive, computed, onMounted } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { Refresh, Search } from '@element-plus/icons-vue'
 import { useRoute } from 'vue-router'
-import { getDailyReportList } from '@/api/dailyCreativeReport'
+import { getDailyReportList, getAvgROI } from '@/api/dailyCreativeReport'
 import { getAccountGroupListAll } from '@/api/accountGroup'
 import dayjs from 'dayjs'
 import { allForSelect } from '@/api/adPlanConf'
@@ -270,6 +220,8 @@ const route = useRoute()
 const loading = ref(false)
 const syncing = ref(false)
 const reportList = ref([])
+const avgRoi = ref({})
+
 const groupOptions = ref([])
 const groupNameMap = ref({})
 const getGroupName = (id) => groupNameMap.value[id] || ''
@@ -293,7 +245,7 @@ const queryForm = reactive({
 const getDefaultDateRange = () => {
   const end = new Date()
   const start = new Date()
-  start.setDate(start.getDate() - 7)
+  start.setDate(start.getDate())
   const fmt = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
   return [fmt(start), fmt(end)]
 }
@@ -343,6 +295,13 @@ const loadList = async () => {
     } else {
       ElMessage.error(res.message || '查询失败')
     }
+
+    const avgROIRes = await getAvgROI(params)
+    if (avgROIRes.success) {
+      avgRoi.value = avgROIRes.data
+    } else {
+      ElMessage.error(avgROIRes.message || '查询平均ROI失败')
+    }
   } catch (err) {
     console.error('查询日报表失败:', err)
     ElMessage.error('查询失败')
@@ -352,7 +311,7 @@ const loadList = async () => {
 }
 
 
-const goToTencentByAccountId  = (row) => {
+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')
 }

+ 24 - 0
src/main/java/com/moka/gdtauto/controller/DailyCreativeReportController.java

@@ -1,5 +1,7 @@
 package com.moka.gdtauto.controller;
 
+import java.math.BigDecimal;
+
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -60,4 +62,26 @@ public class DailyCreativeReportController {
             return Result.fail("查询失败:" + e.getMessage());
         }
     }
+
+
+    @GetMapping("/avg-roi")
+    public Result<BigDecimal> avgRoi(
+            @Parameter(description = "时间口径 REQUEST_TIME / REPORTING_TIME")
+            @RequestParam(defaultValue = "REQUEST_TIME") String timeLine,
+            @Parameter(description = "配置ID(可选)") @RequestParam(required = false) Long confId,
+            @Parameter(description = "账号组ID(可选)") @RequestParam(required = false) Long groupId,
+            @Parameter(description = "广告账户ID(可选)") @RequestParam(required = false) Long accountId,
+            @Parameter(description = "广告ID(可选)") @RequestParam(required = false) Long adgroupId,
+            @Parameter(description = "动态创意ID(可选)") @RequestParam(required = false) Long dynamicCreativeId,
+            @Parameter(description = "开始日期 yyyy-MM-dd(可选)") @RequestParam(required = false) String startDate,
+            @Parameter(description = "结束日期 yyyy-MM-dd(可选)") @RequestParam(required = false) String endDate) {
+        try {
+            BigDecimal result =
+                    dailyReportService.avgROI(timeLine, confId, groupId, accountId, adgroupId, dynamicCreativeId, startDate, endDate);
+            return Result.success(result, "查询成功");
+        } catch (Exception e) { 
+            log.error("查询日报表失败 timeLine={} confId={} groupId={} accountId={} dynamicCreativeId={}", timeLine, confId, groupId, accountId, dynamicCreativeId, e);
+            return Result.fail("查询失败:" + e.getMessage());
+        }
+    }
 }

+ 5 - 0
src/main/java/com/moka/gdtauto/mapper/RepDailyCreativeReportMapper.java

@@ -1,5 +1,6 @@
 package com.moka.gdtauto.mapper;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 import org.apache.ibatis.annotations.Mapper;
@@ -23,4 +24,8 @@ public interface RepDailyCreativeReportMapper extends BaseMapper<RepDailyCreativ
      * @param list 报表数据列表
      */
     void batchUpsert(@Param("list") List<RepDailyCreativeReport> list);
+
+    BigDecimal avgROI(@Param("confId") Long confId, @Param("groupId") Long groupId, @Param("accountId") Long accountId,
+            @Param("adgroupId") Long adgroupId, @Param("dynamicCreativeId") Long dynamicCreativeId,
+            @Param("startDate") String startDate, @Param("endDate") String endDate);
 }

+ 5 - 0
src/main/java/com/moka/gdtauto/mapper/ReqDailyCreativeReportMapper.java

@@ -1,5 +1,6 @@
 package com.moka.gdtauto.mapper;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 import org.apache.ibatis.annotations.Mapper;
@@ -23,4 +24,8 @@ public interface ReqDailyCreativeReportMapper extends BaseMapper<ReqDailyCreativ
      * @param list 报表数据列表
      */
     void batchUpsert(@Param("list") List<ReqDailyCreativeReport> list);
+
+    BigDecimal avgROI(@Param("confId") Long confId, @Param("groupId") Long groupId, @Param("accountId") Long accountId,
+            @Param("adgroupId") Long adgroupId, @Param("dynamicCreativeId") Long dynamicCreativeId,
+            @Param("startDate") String startDate, @Param("endDate") String endDate);
 }

+ 11 - 0
src/main/java/com/moka/gdtauto/service/DailyCreativeReportService.java

@@ -488,4 +488,15 @@ public class DailyCreativeReportService {
     private BigDecimal d2b(Double d) {
         return d == null ? null : BigDecimal.valueOf(d);
     }
+
+    public BigDecimal avgROI(String timeLine, Long confId, Long groupId, Long accountId, Long adgroupId,
+            Long dynamicCreativeId, String startDate, String endDate) {
+        if ("REPORTING_TIME".equals(timeLine)) {
+            BigDecimal roi = repMapper.avgROI(confId, groupId, accountId, adgroupId, dynamicCreativeId, startDate, endDate);
+            return roi;
+        } else {
+            BigDecimal roi = reqMapper.avgROI(confId, groupId, accountId, adgroupId, dynamicCreativeId, startDate, endDate);
+            return roi;
+        }
+    }
 }

+ 27 - 0
src/main/resources/mapper/RepDailyCreativeReportMapper.xml

@@ -202,4 +202,31 @@
             income_val_24h = VALUES(income_val_24h), income_roi_1_24h = VALUES(income_roi_1_24h)
     </insert>
 
+    <select id="avgROI">
+        select sum(income_val_1)/sum(cost) from rep_daily_creative_report
+        <where>
+            <if test="confId != null">
+              and conf_id = #{confId}
+            </if>
+            <if test="groupId != null">
+              and group_id = #{groupId}
+            </if>
+            <if test="accountId != null">
+              and account_id = #{accountId}
+            </if>
+            <if test="adgroupId != null">
+              and adgroup_id = #{adgroupId}
+            </if>
+            <if test="dynamicCreativeId != null">
+              and dynamic_creative_id = #{dynamicCreativeId}
+            </if>
+            <if test="startDate != null">
+              and date <![CDATA[>=]]> #{startDate}
+            </if>
+            <if test="endDate != null">
+               and date <![CDATA[<=]]> #{endDate}
+            </if>
+        </where>
+    </select>
+
 </mapper>

+ 28 - 0
src/main/resources/mapper/ReqDailyCreativeReportMapper.xml

@@ -201,4 +201,32 @@
             income_val_24h = VALUES(income_val_24h), income_roi_1_24h = VALUES(income_roi_1_24h)
     </insert>
 
+    <!-- avgROI --> 
+
+    <select id="avgROI">
+     select sum(income_val_1)/sum(cost) from req_daily_creative_report 
+     <where>
+        <if test="confId != null">
+           and conf_id = #{confId}
+        </if>
+        <if test="groupId != null">
+           and group_id = #{groupId}
+        </if>
+        <if test="accountId != null">
+           and account_id = #{accountId}
+        </if>
+        <if test="adgroupId != null">
+           and adgroup_id = #{adgroupId}
+        </if>
+        <if test="dynamicCreativeId != null">
+           and dynamic_creative_id = #{dynamicCreativeId}
+        </if>
+        <if test="startDate != null">
+           and date <![CDATA[>=]]> #{startDate}
+        </if>
+        <if test="endDate != null">
+           and date <![CDATA[<=]]> #{endDate}
+        </if>
+        </where>
+    </select>
 </mapper>

Some files were not shown because too many files changed in this diff