wfansh преди 3 месеца
родител
ревизия
7db19ef4a1

+ 8 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/common/enums/CountryCode.java

@@ -272,10 +272,18 @@ public enum CountryCode {
             Stream.of(CountryCode.values())
                     .collect(Collectors.toMap(CountryCode::getCode, Function.identity()));
 
+    private static final Map<String, CountryCode> NAME_MAP =
+            Stream.of(CountryCode.values())
+                    .collect(Collectors.toMap(CountryCode::getName, Function.identity()));
+
     public static CountryCode valueOfCode(String code) {
         return CODE_MAP.getOrDefault(code, UNK);
     }
 
+    public static CountryCode valueOfName(String name) {
+        return NAME_MAP.getOrDefault(name, UNK);
+    }
+
     private final String code;
     private final String name;
     private final String cnName;

+ 8 - 4
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/dmp/controller/DMPDataController.java

@@ -92,7 +92,8 @@ public class DMPDataController {
         }
 
         // 2. 查询并返回
-        return Result.ok(gaCountryReportService.getCountryStats(siteCode, start, end));
+        // return Result.ok(gaCountryReportService.getCountryStats(siteCode, start, end));
+        return Result.ok(dmpReportService.getCountryStats(siteCode, start, end));
     }
 
     @GetMapping("/source-medium/stats")
@@ -109,7 +110,8 @@ public class DMPDataController {
         }
 
         // 2. 查询并返回
-        return Result.ok(gaSourceMediumReportService.getSourceMediumStats(siteCode, start, end));
+        // return Result.ok(gaSourceMediumReportService.getSourceMediumStats(siteCode, start, end));
+        return Result.ok(dmpReportService.getSourceMediumStats(siteCode, start, end));
     }
 
     @GetMapping("/page-path/stats")
@@ -127,9 +129,11 @@ public class DMPDataController {
         }
 
         // 2. 查询并返回
+        // return Result.ok(
+        //        gaPagePathReportService.getPagePathStats(
+        //                siteCode, start, end, limit >= 0 ? limit : 10));
         return Result.ok(
-                gaPagePathReportService.getPagePathStats(
-                        siteCode, start, end, limit >= 0 ? limit : 10));
+                dmpReportService.getPagePathStats(siteCode, start, end, limit >= 0 ? limit : 10));
     }
 
     @GetMapping("/device/stats")

+ 150 - 4
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/dmp/service/DMPReportService.java

@@ -1,12 +1,14 @@
 package org.jeecg.modules.adweb.dmp.service;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.google.common.base.Strings;
 
 import lombok.extern.slf4j.Slf4j;
 
 import org.apache.commons.compress.utils.Lists;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
+import org.jeecg.modules.adweb.common.enums.CountryCode;
 import org.jeecg.modules.adweb.common.util.AdwebRedisUtil;
 import org.jeecg.modules.adweb.common.util.DateUtil;
 import org.jeecg.modules.adweb.common.util.NumberUtil;
@@ -18,8 +20,12 @@ import org.jeecg.modules.adweb.dmp.dto.google.analytics.report.ReportType;
 import org.jeecg.modules.adweb.dmp.dto.google.analytics.report.data.CustomReportData;
 import org.jeecg.modules.adweb.dmp.entity.GoogleGTM;
 import org.jeecg.modules.adweb.dmp.service.google.GAReportService;
+import org.jeecg.modules.adweb.dmp.vo.report.CountryStatsVO;
 import org.jeecg.modules.adweb.dmp.vo.report.DeviceStatsVO;
+import org.jeecg.modules.adweb.dmp.vo.report.PagePathStatsVO;
 import org.jeecg.modules.adweb.dmp.vo.report.SourceMediumStatsVO;
+import org.jeecg.modules.adweb.site.entity.AdwebSite;
+import org.jeecg.modules.adweb.site.service.IAdwebSiteService;
 import org.jeecg.modules.redis.CacheConfig;
 import org.jeecg.modules.redis.TTLCacheManager;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -29,7 +35,7 @@ import org.springframework.stereotype.Service;
 import java.util.*;
 
 /**
- * 从DataBridge直接生成GA报表数据,跳过DB查询 - http://data-bridge.v3.adwebcloud.com:9002/swagger-ui/index.html
+ * 从DataBridge直接生成GA报表数据,不依赖DB查询 - http://data-bridge.v3.adwebcloud.com:9002/swagger-ui/index.html
  *
  * @author wfansh
  */
@@ -37,10 +43,75 @@ import java.util.*;
 @Slf4j
 public class DMPReportService {
 
+    @Autowired private IAdwebSiteService adwebSiteService;
     @Autowired private IGoogleGTMService googleGTMService;
     @Autowired private GAReportService gaReportService;
     @Autowired private AdwebRedisUtil redisUtil;
 
+    /** 拉取Google Analytics - Country报表 */
+    @Cacheable(
+            cacheManager = CacheConfig.TTL_CACHE_MANAGER,
+            cacheNames =
+                    "dmp:getCountryStats"
+                            + TTLCacheManager.TTL_SPLITTER
+                            + 60 * 10) // Redis TTL为10分钟
+    public List<CountryStatsVO> getCountryStats(String siteCode, Date start, Date end) {
+        GoogleGTM googleGTM = this.getGTMAccount(siteCode);
+        if (StringUtils.isBlank(googleGTM.getGaPropertyId())) {
+            log.info("Google Analytics帐号未配置, siteCode = {}", siteCode);
+            return Collections.EMPTY_LIST;
+        }
+
+        // 1. 构建GA报表请求参数
+        // 使用ReportType.ADWEB_CUSTOM_REPORT
+        Pair<String, String> dateRange = this.getDateRange(start, end);
+
+        GAReportRequestDTO gaReportRequest = new GAReportRequestDTO();
+        gaReportRequest.setPropertyResourceName(
+                GAPropertyDTO.toResourceName(googleGTM.getGaPropertyId()));
+        gaReportRequest.setReportType(ReportType.ADWEB_CUSTOM_REPORT);
+        gaReportRequest.setStartDate(dateRange.getLeft());
+        gaReportRequest.setEndDate(dateRange.getRight());
+        gaReportRequest.setMetrics(List.of(ReportConstant.METRIC_TOTAL_USERS));
+        gaReportRequest.setDimensions(List.of(ReportConstant.DIMENSION_COUNTRY));
+        gaReportRequest.setOrderByType(OrderByType.METRICS);
+        gaReportRequest.setOrderBy(ReportConstant.METRIC_TOTAL_USERS);
+        gaReportRequest.setOrderByDesc(true);
+
+        // 2. 请求API接口
+        List<CustomReportData> reportDataList =
+                gaReportService.runGAReport(gaReportRequest, CustomReportData.class);
+
+        // 3.1 转化为VOs
+        List<CountryStatsVO> countryStatsVOs = Lists.newArrayList();
+        for (CustomReportData reportData : reportDataList) {
+            CountryStatsVO countryStatsVO = new CountryStatsVO();
+            countryStatsVO.setCountry(reportData.get(ReportConstant.DIMENSION_COUNTRY));
+
+            CountryCode countryCode = CountryCode.valueOfName(countryStatsVO.getCountry());
+            countryStatsVO.setCountryName(countryCode.getCnName());
+            countryStatsVO.setCountryCode(countryCode.getCode());
+
+            countryStatsVO.setTotalUsers(
+                    Integer.parseInt(reportData.get(ReportConstant.METRIC_TOTAL_USERS)));
+
+            countryStatsVOs.add(countryStatsVO);
+        }
+
+        // 3.2 时间区间内所有国家totalUsers总数
+        int totalUsersSum = countryStatsVOs.stream().mapToInt(CountryStatsVO::getTotalUsers).sum();
+
+        // 3.3 VO数据计算填充
+        for (CountryStatsVO countryStatsVO : countryStatsVOs) {
+            countryStatsVO.setTotalUsersProportion(
+                    NumberUtil.formatPercentage(
+                            NumberUtil.safeDivide(countryStatsVO.getTotalUsers(), totalUsersSum),
+                            2));
+        }
+
+        return countryStatsVOs;
+    }
+
     /** 拉取Google Analytics - Session Source Medium报表 */
     @Cacheable(
             cacheManager = CacheConfig.TTL_CACHE_MANAGER,
@@ -82,7 +153,7 @@ public class DMPReportService {
         List<CustomReportData> reportDataList =
                 gaReportService.runGAReport(gaReportRequest, CustomReportData.class);
 
-        // 2.1 转化为VOs
+        // 3.1 转化为VOs
         List<SourceMediumStatsVO> sourceMediumStatsVOs = Lists.newArrayList();
         for (CustomReportData reportData : reportDataList) {
             SourceMediumStatsVO sourceMediumStatsVO = new SourceMediumStatsVO();
@@ -115,11 +186,11 @@ public class DMPReportService {
             sourceMediumStatsVOs.add(sourceMediumStatsVO);
         }
 
-        // 2.2 时间区间内所有媒介totalUsers总数
+        // 3.2 时间区间内所有媒介totalUsers总数
         int totalUsersSum =
                 sourceMediumStatsVOs.stream().mapToInt(SourceMediumStatsVO::getTotalUsers).sum();
 
-        // 2.3 VO数据计算填充
+        // 3.3 VO数据计算填充
         for (SourceMediumStatsVO sourceMediumStatsVO : sourceMediumStatsVOs) {
             int totalUsers = sourceMediumStatsVO.getTotalUsers();
             sourceMediumStatsVO.setTotalUsersProportion(
@@ -135,6 +206,81 @@ public class DMPReportService {
         return sourceMediumStatsVOs;
     }
 
+    /** 拉取Google Analytics - Page Path报表 */
+    @Cacheable(
+            cacheManager = CacheConfig.TTL_CACHE_MANAGER,
+            cacheNames =
+                    "dmp:getPagePathStats"
+                            + TTLCacheManager.TTL_SPLITTER
+                            + 60 * 10) // Redis TTL为10分钟
+    public List<PagePathStatsVO> getPagePathStats(
+            String siteCode, Date start, Date end, int limit) {
+        GoogleGTM googleGTM = this.getGTMAccount(siteCode);
+        if (StringUtils.isBlank(googleGTM.getGaPropertyId())) {
+            log.info("Google Analytics帐号未配置, siteCode = {}", siteCode);
+            return Collections.EMPTY_LIST;
+        }
+
+        // 1. 构建GA报表请求参数
+        // 使用ReportType.ADWEB_CUSTOM_REPORT
+        Pair<String, String> dateRange = this.getDateRange(start, end);
+
+        GAReportRequestDTO gaReportRequest = new GAReportRequestDTO();
+        gaReportRequest.setPropertyResourceName(
+                GAPropertyDTO.toResourceName(googleGTM.getGaPropertyId()));
+        gaReportRequest.setReportType(ReportType.ADWEB_CUSTOM_REPORT);
+        gaReportRequest.setStartDate(dateRange.getLeft());
+        gaReportRequest.setEndDate(dateRange.getRight());
+        gaReportRequest.setMetrics(
+                List.of(
+                        ReportConstant.METRIC_SCREEN_PAGE_VIEWS,
+                        ReportConstant.METRIC_USER_ENGAGEMENT_DURATION));
+        gaReportRequest.setDimensions(List.of(ReportConstant.DIMENSION_PAGE_PATH));
+        gaReportRequest.setOrderByType(OrderByType.METRICS);
+        gaReportRequest.setOrderBy(ReportConstant.METRIC_SCREEN_PAGE_VIEWS);
+        gaReportRequest.setOrderByDesc(true);
+
+        // 2. 请求API接口
+        List<CustomReportData> reportDataList =
+                gaReportService.runGAReport(gaReportRequest, CustomReportData.class);
+
+        // 3.1 转化为VOs
+        List<PagePathStatsVO> pagePathStatsVOs = Lists.newArrayList();
+        for (CustomReportData reportData : reportDataList) {
+            PagePathStatsVO pagePathStatsVO = new PagePathStatsVO();
+            pagePathStatsVO.setPagePath(reportData.get(ReportConstant.DIMENSION_PAGE_PATH));
+            pagePathStatsVO.setPageViews(
+                    Integer.parseInt(reportData.get(ReportConstant.METRIC_SCREEN_PAGE_VIEWS)));
+            pagePathStatsVO.setAvgTimeOnPage(
+                    NumberUtil.formatDecimal(
+                                    Double.parseDouble(
+                                            reportData.get(
+                                                    ReportConstant
+                                                            .METRIC_USER_ENGAGEMENT_DURATION)),
+                                    2)
+                            .doubleValue());
+
+            pagePathStatsVOs.add(pagePathStatsVO);
+        }
+
+        // 3.2. 网站URL及格式化
+        AdwebSite adwebSite = adwebSiteService.getSiteByCode(siteCode);
+        String siteUrl = StringUtils.removeEnd(Strings.nullToEmpty(adwebSite.getDomain()), "/");
+
+        // 3.3. 时间区间内PV总数
+        int totalPVs = pagePathStatsVOs.stream().mapToInt(PagePathStatsVO::getPageViews).sum();
+
+        // 3.4 VO数据计算填充
+        for (PagePathStatsVO pagePathStatsVO : pagePathStatsVOs) {
+            pagePathStatsVO.setPagePath(siteUrl + pagePathStatsVO.getPagePath());
+            pagePathStatsVO.setPvProportion(
+                    NumberUtil.formatPercentage(
+                            NumberUtil.safeDivide(pagePathStatsVO.getPageViews(), totalPVs), 2));
+        }
+
+        return pagePathStatsVOs.subList(0, Math.min(pagePathStatsVOs.size(), limit));
+    }
+
     /** 拉取Google Analytics - Device报表 */
     @Cacheable(
             cacheManager = CacheConfig.TTL_CACHE_MANAGER,