|
@@ -9,9 +9,12 @@ import com.google.common.collect.Sets;
|
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
import org.apache.commons.compress.utils.Lists;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.apache.commons.lang3.tuple.ImmutablePair;
|
|
|
import org.apache.commons.lang3.tuple.ImmutableTriple;
|
|
|
+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;
|
|
@@ -35,6 +38,7 @@ import org.springframework.cache.annotation.Cacheable;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.util.*;
|
|
|
+import java.util.function.Function;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
@@ -55,13 +59,104 @@ public class RealtimeReportService {
|
|
|
@Autowired private AdwebRedisUtil adwebRedisUtil;
|
|
|
|
|
|
/**
|
|
|
- * 拉取Google Analytics - 时间段报表 - 今天,昨天,本周,上周,本月,上月,全部
|
|
|
+ * 拉取Google Analytics - Period报表(today, yesterday, thisWeek, lastWeek, thisMonth, lastMonth,
|
|
|
+ * allTime)
|
|
|
*
|
|
|
* <p>填充各时间段询盘数据
|
|
|
*/
|
|
|
+ @Cacheable(
|
|
|
+ cacheManager = CacheConfig.TTL_CACHE_MANAGER,
|
|
|
+ cacheNames =
|
|
|
+ "dmp:realtime:getPeriodicStats"
|
|
|
+ + TTLCacheManager.TTL_SPLITTER
|
|
|
+ + 60 * 10) // Redis TTL为10分钟
|
|
|
public List<PeriodicStatsVO> getPeriodicStats(String siteCode) {
|
|
|
- // TODO
|
|
|
- return Collections.EMPTY_LIST;
|
|
|
+ GoogleGTM googleGTM = this.getGTMAccount(siteCode);
|
|
|
+ if (StringUtils.isBlank(googleGTM.getGaPropertyId())) {
|
|
|
+ log.info("Google Analytics帐号未配置, siteCode = {}", siteCode);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1. 查询GA统计数据 - UV,PV等
|
|
|
+ Map<String, PeriodicStatsVO> periodicStatsVOs =
|
|
|
+ List.of(
|
|
|
+ DateUtil.DATE_TYPE_TODAY,
|
|
|
+ DateUtil.DATE_TYPE_YESTERDAY,
|
|
|
+ DateUtil.DATE_TYPE_THIS_WEEK,
|
|
|
+ DateUtil.DATE_TYPE_LAST_WEEK,
|
|
|
+ DateUtil.DATE_TYPE_THIS_MONTH,
|
|
|
+ DateUtil.DATE_TYPE_LAST_MONTH,
|
|
|
+ DateUtil.DATE_TYPE_ALL_TIME)
|
|
|
+ .parallelStream()
|
|
|
+ .map(period -> this.getPeriodicStats(googleGTM.getGaPropertyId(), period))
|
|
|
+ .collect(
|
|
|
+ Collectors.toMap(
|
|
|
+ PeriodicStatsVO::getPeriod,
|
|
|
+ Function.identity(),
|
|
|
+ (x, y) -> y,
|
|
|
+ LinkedHashMap::new)); // 使用LinkedHashMap保持原查询顺序
|
|
|
+
|
|
|
+ // 2. 询盘数据补充
|
|
|
+ List<ImmutablePair<String, Long>> enquiryPeriodicCounts =
|
|
|
+ adwebEnquiryMapper.getEnquiryPeriodicCounts(siteCode);
|
|
|
+ for (ImmutablePair<String, Long> enquiryPeriodicCount : enquiryPeriodicCounts) {
|
|
|
+ if (!periodicStatsVOs.containsKey(enquiryPeriodicCount.getKey())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ PeriodicStatsVO periodicStatsVO = periodicStatsVOs.get(enquiryPeriodicCount.getKey());
|
|
|
+ periodicStatsVO.setEnquires(enquiryPeriodicCount.getValue().intValue());
|
|
|
+ periodicStatsVO.setEnquiryConversionRate(
|
|
|
+ NumberUtil.formatPercentage(
|
|
|
+ NumberUtil.safeDivide(
|
|
|
+ periodicStatsVO.getEnquires(), periodicStatsVO.getTotalUsers()),
|
|
|
+ 2));
|
|
|
+ }
|
|
|
+
|
|
|
+ return periodicStatsVOs.values().stream()
|
|
|
+ .collect(Collectors.toList()); // 使用toList()方法返回UnmodifiableList,导致Redis类型解析异常
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 拉取Google Analytics - 指定Period报表
|
|
|
+ *
|
|
|
+ * <p>see {@link #getPeriodicStats(String)}
|
|
|
+ */
|
|
|
+ private PeriodicStatsVO getPeriodicStats(String propertyId, String period) {
|
|
|
+ // 0. 计算时间区间
|
|
|
+ Pair<Date, Date> dateRange = DateUtil.getDateRangeByType(period);
|
|
|
+
|
|
|
+ List<CustomReportData> reportDataList = Lists.newArrayList();
|
|
|
+ if (StringUtils.isNotBlank(propertyId)) {
|
|
|
+ // 1. 构建GA报表请求参数
|
|
|
+ GAReportRequestDTO gaReportRequest =
|
|
|
+ this.buildGAReportRequest(
|
|
|
+ propertyId,
|
|
|
+ dateRange.getLeft(),
|
|
|
+ dateRange.getRight(),
|
|
|
+ List.of(
|
|
|
+ ReportConstant.METRIC_TOTAL_USERS,
|
|
|
+ ReportConstant.METRIC_SCREEN_PAGE_VIEWS),
|
|
|
+ List.of(),
|
|
|
+ OrderByType.METRICS,
|
|
|
+ ReportConstant.METRIC_TOTAL_USERS,
|
|
|
+ true);
|
|
|
+
|
|
|
+ // 2. 请求API接口
|
|
|
+ reportDataList = gaReportService.runGAReport(gaReportRequest, CustomReportData.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 转化为VO
|
|
|
+ PeriodicStatsVO periodicStatsVO = new PeriodicStatsVO();
|
|
|
+ periodicStatsVO.setPeriod(period);
|
|
|
+ if (CollectionUtils.isNotEmpty(reportDataList)) {
|
|
|
+ periodicStatsVO.setTotalUsers(
|
|
|
+ Integer.parseInt(reportDataList.get(0).get(ReportConstant.METRIC_TOTAL_USERS)));
|
|
|
+ periodicStatsVO.setPageViews(
|
|
|
+ Integer.parseInt(
|
|
|
+ reportDataList.get(0).get(ReportConstant.METRIC_SCREEN_PAGE_VIEWS)));
|
|
|
+ }
|
|
|
+
|
|
|
+ return periodicStatsVO;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -79,10 +174,6 @@ public class RealtimeReportService {
|
|
|
+ 60 * 10) // Redis TTL为10分钟
|
|
|
public List<DailyStatsVO> getDailyStats(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;
|
|
|
- }
|
|
|
|
|
|
// 0. 起止日期为空时,设置默认区间 - start = 网站发布日期 & end = 今天
|
|
|
if (start == null || end == null) {
|
|
@@ -94,27 +185,31 @@ public class RealtimeReportService {
|
|
|
end = DateUtil.getTodayZeroTime(new Date());
|
|
|
}
|
|
|
|
|
|
- // 1. 构建GA报表请求参数
|
|
|
- GAReportRequestDTO gaReportRequest =
|
|
|
- this.buildGAReportRequest(
|
|
|
- googleGTM.getGaPropertyId(),
|
|
|
- start,
|
|
|
- end,
|
|
|
- List.of(
|
|
|
- ReportConstant.METRIC_TOTAL_USERS,
|
|
|
- ReportConstant.METRIC_SESSIONS,
|
|
|
- ReportConstant.METRIC_BOUNCE_RATE,
|
|
|
- ReportConstant.METRIC_AVG_SESSION_DURATION,
|
|
|
- ReportConstant.METRIC_SCREEN_PAGE_VIEWS,
|
|
|
- ReportConstant.METRIC_SCREEN_PAGE_VIEWS_PER_SESSION),
|
|
|
- List.of(ReportConstant.DIMENSION_DATE),
|
|
|
- OrderByType.DIMENSIONS,
|
|
|
- ReportConstant.DIMENSION_DATE,
|
|
|
- false);
|
|
|
-
|
|
|
- // 2. 请求API接口
|
|
|
- List<CustomReportData> reportDataList =
|
|
|
- gaReportService.runGAReport(gaReportRequest, CustomReportData.class);
|
|
|
+ List<CustomReportData> reportDataList = Lists.newArrayList();
|
|
|
+ if (StringUtils.isBlank(googleGTM.getGaPropertyId())) {
|
|
|
+ log.info("Google Analytics帐号未配置, siteCode = {}", siteCode);
|
|
|
+ } else {
|
|
|
+ // 1. 构建GA报表请求参数
|
|
|
+ GAReportRequestDTO gaReportRequest =
|
|
|
+ this.buildGAReportRequest(
|
|
|
+ googleGTM.getGaPropertyId(),
|
|
|
+ start,
|
|
|
+ end,
|
|
|
+ List.of(
|
|
|
+ ReportConstant.METRIC_TOTAL_USERS,
|
|
|
+ ReportConstant.METRIC_SESSIONS,
|
|
|
+ ReportConstant.METRIC_BOUNCE_RATE,
|
|
|
+ ReportConstant.METRIC_AVG_SESSION_DURATION,
|
|
|
+ ReportConstant.METRIC_SCREEN_PAGE_VIEWS,
|
|
|
+ ReportConstant.METRIC_SCREEN_PAGE_VIEWS_PER_SESSION),
|
|
|
+ List.of(ReportConstant.DIMENSION_DATE),
|
|
|
+ OrderByType.DIMENSIONS,
|
|
|
+ ReportConstant.DIMENSION_DATE,
|
|
|
+ false);
|
|
|
+
|
|
|
+ // 2. 请求API接口
|
|
|
+ reportDataList = gaReportService.runGAReport(gaReportRequest, CustomReportData.class);
|
|
|
+ }
|
|
|
|
|
|
// 3. 转化为VOs
|
|
|
Map<String, DailyStatsVO> dailyStatsVOs = Maps.newHashMap();
|
|
@@ -317,7 +412,12 @@ public class RealtimeReportService {
|
|
|
2));
|
|
|
}
|
|
|
|
|
|
- return sourceMediumStatsVOs;
|
|
|
+ return sourceMediumStatsVOs.stream()
|
|
|
+ .sorted(
|
|
|
+ Comparator.comparingInt(SourceMediumStatsVO::getTotalUsers)
|
|
|
+ .thenComparingDouble(SourceMediumStatsVO::getAvgSessionDuration)
|
|
|
+ .reversed())
|
|
|
+ .collect(Collectors.toList()); // 使用toList()方法返回UnmodifiableList,导致Redis类型解析异常
|
|
|
}
|
|
|
|
|
|
/** 拉取Google Analytics - Page Path报表 */
|
|
@@ -388,6 +488,10 @@ public class RealtimeReportService {
|
|
|
}
|
|
|
|
|
|
return pagePathStatsVOs.stream()
|
|
|
+ .sorted(
|
|
|
+ Comparator.comparingInt(PagePathStatsVO::getPageViews)
|
|
|
+ .thenComparingDouble(PagePathStatsVO::getAvgTimeOnPage)
|
|
|
+ .reversed())
|
|
|
.limit(limit)
|
|
|
.collect(Collectors.toList()); // 使用toList()方法返回UnmodifiableList,导致Redis类型解析异常
|
|
|
}
|