|
@@ -84,7 +84,7 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
.map(date -> calculateNewUserCount(date, version, reqDto.getChannel(), reqDto.getTimeUnit(), "newUser"))
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
- trend.setData(counts);
|
|
|
+// trend.setData(counts);
|
|
|
return trend;
|
|
|
})
|
|
|
.collect(Collectors.toList());
|
|
@@ -284,13 +284,47 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
* @return GetNewUserTrendVO
|
|
|
*/
|
|
|
@Override
|
|
|
-
|
|
|
public GetNewUserTrendVO getActiveTrend(UserAnalyseQueryBaseDTO reqDto) {
|
|
|
GetNewUserTrendVO result = new GetNewUserTrendVO();
|
|
|
// 1. 生成时间轴
|
|
|
List<String> dates = generateTimeAxis(reqDto.getFromDate(), reqDto.getToDate(), reqDto.getTimeUnit());
|
|
|
result.setDates(dates);
|
|
|
|
|
|
+ // 2. 处理版本列表(为空时按null处理)
|
|
|
+ List<String> versions = reqDto.getVersion();
|
|
|
+ List<String> processVersions = (versions == null || versions.isEmpty())
|
|
|
+ ? Collections.singletonList(null)
|
|
|
+ : versions.stream().filter(v -> v != null && !v.isEmpty()).toList();
|
|
|
+
|
|
|
+ // 3. 处理每个版本的数据
|
|
|
+ List<TrendBaseVO> voList = processVersions.stream()
|
|
|
+ .map(version -> {
|
|
|
+ TrendBaseVO trend = new TrendBaseVO();
|
|
|
+ trend.setName("活跃用户");
|
|
|
+ trend.setVersion(version);
|
|
|
+ trend.setKey("activeUser");
|
|
|
+
|
|
|
+ // 计算每个时间点的活跃用户数
|
|
|
+ List<Long> counts = dates.stream()
|
|
|
+ .map(date -> {
|
|
|
+ LocalDateTime startTime = getStartTime(date, reqDto.getTimeUnit());
|
|
|
+ LocalDateTime endTime = getEndTime(date, reqDto.getTimeUnit());
|
|
|
+ return statActiveUserCount(startTime, endTime, reqDto.getAppId(), version, reqDto.getChannel());
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ trend.setData(counts);
|
|
|
+ return trend;
|
|
|
+ })
|
|
|
+ .toList();
|
|
|
+ result.setItems(voList);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ public GetNewUserTrendVO getActiveTrend2(UserAnalyseQueryBaseDTO reqDto) {
|
|
|
+ GetNewUserTrendVO result = new GetNewUserTrendVO();
|
|
|
+ // 1. 生成时间轴
|
|
|
+ List<String> dates = generateTimeAxis(reqDto.getFromDate(), reqDto.getToDate(), reqDto.getTimeUnit());
|
|
|
+ result.setDates(dates);
|
|
|
+
|
|
|
// 2. 处理版本列表(为空时按"All"处理)
|
|
|
List<String> versions = reqDto.getVersion();
|
|
|
List<String> processVersions = (versions == null || versions.isEmpty())
|
|
@@ -310,7 +344,7 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
.map(date -> calculateNewUserCount(date, version, reqDto.getChannel(), reqDto.getTimeUnit(), "activeUser"))
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
- trend.setData(counts);
|
|
|
+// trend.setData(counts);
|
|
|
return trend;
|
|
|
})
|
|
|
.collect(Collectors.toList());
|
|
@@ -326,105 +360,59 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
*/
|
|
|
@Override
|
|
|
public GetActiveUserBaseVO getActiveCompose(UserAnalyseQueryBaseDTO reqDto) {
|
|
|
- // 创建返回对象
|
|
|
- GetActiveUserBaseVO result = new GetActiveUserBaseVO();
|
|
|
- Random random = new Random();
|
|
|
-
|
|
|
- // 1. 生成日期列表
|
|
|
- List<String> dates = new ArrayList<>();
|
|
|
- LocalDate startDate = reqDto.getFromDate();
|
|
|
- LocalDate endDate = reqDto.getToDate();
|
|
|
- LocalDateTime currentDateTime = LocalDateTime.of(startDate, LocalTime.MIN);
|
|
|
- LocalDateTime endDateTime = LocalDateTime.of(endDate, LocalTime.MAX);
|
|
|
-
|
|
|
- // 根据时间单位生成对应日期
|
|
|
- while (!currentDateTime.isAfter(endDateTime)) {
|
|
|
- String dateStr;
|
|
|
- switch (reqDto.getTimeUnit()) {
|
|
|
- case "hour":
|
|
|
- dateStr = currentDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
|
|
|
- currentDateTime = currentDateTime.plusHours(1);
|
|
|
- break;
|
|
|
- case "day":
|
|
|
- dateStr = currentDateTime.toLocalDate().format(DateTimeFormatter.ISO_LOCAL_DATE);
|
|
|
- currentDateTime = currentDateTime.plusDays(1);
|
|
|
- break;
|
|
|
- case "week":
|
|
|
- LocalDate weekStart = currentDateTime.toLocalDate();
|
|
|
- LocalDate weekEnd = weekStart.plusDays(6);
|
|
|
- if (weekEnd.isAfter(endDate)) {
|
|
|
- weekEnd = endDate;
|
|
|
- }
|
|
|
- dateStr = weekStart.format(DateTimeFormatter.ISO_LOCAL_DATE) + "~" +
|
|
|
- weekEnd.format(DateTimeFormatter.ISO_LOCAL_DATE);
|
|
|
- currentDateTime = currentDateTime.plusWeeks(1);
|
|
|
- break;
|
|
|
- case "month":
|
|
|
- LocalDate monthStart = currentDateTime.toLocalDate();
|
|
|
- LocalDate monthEnd = monthStart.plusMonths(1).minusDays(1);
|
|
|
- if (monthEnd.isAfter(endDate)) {
|
|
|
- monthEnd = endDate;
|
|
|
- }
|
|
|
- dateStr = monthStart.withDayOfMonth(1).format(DateTimeFormatter.ISO_LOCAL_DATE) + "~" +
|
|
|
- monthEnd.format(DateTimeFormatter.ISO_LOCAL_DATE);
|
|
|
- currentDateTime = currentDateTime.plusMonths(1);
|
|
|
- break;
|
|
|
- default:
|
|
|
- dateStr = currentDateTime.toLocalDate().format(DateTimeFormatter.ISO_LOCAL_DATE);
|
|
|
- currentDateTime = currentDateTime.plusDays(1);
|
|
|
- }
|
|
|
- dates.add(dateStr);
|
|
|
+ // 1. 获取时间坐标轴
|
|
|
+ List<String> dates = generateTimeAxis(reqDto.getFromDate(), reqDto.getToDate(), reqDto.getTimeUnit());
|
|
|
+ // 获取版本信息
|
|
|
+ String version = null;
|
|
|
+ if (reqDto.getVersion() != null && !reqDto.getVersion().isEmpty()){
|
|
|
+ version = reqDto.getVersion().get(0);
|
|
|
+ }
|
|
|
+ List<BigDecimal> newCounts = new ArrayList<>();
|
|
|
+ List<BigDecimal> activeCounts = new ArrayList<>();
|
|
|
+ List<BigDecimal> newRates = new ArrayList<>();
|
|
|
+ // 2. 遍历时间坐标轴
|
|
|
+ for (String date : dates) {
|
|
|
+ LocalDateTime startTime = getStartTime(date, reqDto.getTimeUnit());
|
|
|
+ LocalDateTime endTime = getEndTime(date, reqDto.getTimeUnit());
|
|
|
+ // 活跃用户数
|
|
|
+ BigDecimal activeCount = BigDecimal.valueOf(statActiveUserCount(startTime, endTime, reqDto.getAppId(), version, reqDto.getChannel()));
|
|
|
+ activeCounts.add( activeCount);
|
|
|
+ // 活跃用户中的新增用户数
|
|
|
+ BigDecimal newCount = BigDecimal.valueOf(getActiveNewUserCount(startTime, endTime, reqDto.getAppId(), version, reqDto.getChannel()));
|
|
|
+ newCounts.add( newCount);
|
|
|
+ // 新增用户占比
|
|
|
+ BigDecimal newRate = activeCount.compareTo(BigDecimal.ZERO) == 0 || newCount.compareTo(BigDecimal.ZERO) == 0 ?
|
|
|
+ BigDecimal.ZERO:
|
|
|
+ newCount.divide(activeCount, 4, RoundingMode.HALF_UP);
|
|
|
+ newRates.add(newRate);
|
|
|
}
|
|
|
- result.setDates(dates);
|
|
|
|
|
|
- // 2. 生成各项数据(调整为Double类型列表)
|
|
|
+ // 组装结果
|
|
|
List<ActiveUserComposeVO> items = new ArrayList<>();
|
|
|
- int dataSize = dates.size();
|
|
|
|
|
|
- // 活跃用户数据(整数转为Double)
|
|
|
ActiveUserComposeVO activeUser = new ActiveUserComposeVO();
|
|
|
activeUser.setName("活跃用户");
|
|
|
- List<Double> activeData = new ArrayList<>();
|
|
|
- for (int i = 0; i < dataSize; i++) {
|
|
|
- int value = 30000 + random.nextInt(5000) + (i * 50);
|
|
|
- activeData.add((double) value); // 整数转Double
|
|
|
- }
|
|
|
-// activeUser.setData(activeData);
|
|
|
+ activeUser.setData(activeCounts);
|
|
|
+ activeUser.setKey("activeUser");
|
|
|
+ activeUser.setVersion( version == null ? "All" : version);
|
|
|
items.add(activeUser);
|
|
|
|
|
|
- // 新增用户数据(整数转为Double)
|
|
|
ActiveUserComposeVO newUser = new ActiveUserComposeVO();
|
|
|
newUser.setName("新增用户");
|
|
|
- List<Double> newUserData = new ArrayList<>();
|
|
|
- for (int i = 0; i < dataSize; i++) {
|
|
|
- int value = activeData.get(i).intValue() - 100 - random.nextInt(300);
|
|
|
- newUserData.add((double) value); // 整数转Double
|
|
|
- }
|
|
|
-// newUser.setData(newUserData);
|
|
|
+ newUser.setData(newCounts);
|
|
|
+ newUser.setKey("newUser");
|
|
|
+ newUser.setVersion( version == null ? "All" : version);
|
|
|
items.add(newUser);
|
|
|
|
|
|
- // 新增用户占比数据(保持Double类型)
|
|
|
ActiveUserComposeVO newUserRate = new ActiveUserComposeVO();
|
|
|
newUserRate.setName("新增用户占比");
|
|
|
- List<Double> rateData = new ArrayList<>();
|
|
|
- for (int i = 0; i < dataSize; i++) {
|
|
|
- double rate = (newUserData.get(i) / activeData.get(i)) * 100;
|
|
|
- rateData.add(Math.round(rate * 100) / 100.0); // 保留两位小数
|
|
|
- }
|
|
|
-// newUserRate.setData(rateData);
|
|
|
+ newUserRate.setData(newRates);
|
|
|
+ newUserRate.setKey("newUserRate");
|
|
|
+ newUserRate.setVersion( version == null ? "All" : version);
|
|
|
items.add(newUserRate);
|
|
|
|
|
|
- // 老用户数据(计算后转为Double)
|
|
|
- ActiveUserComposeVO oldUser = new ActiveUserComposeVO();
|
|
|
- oldUser.setName("老用户");
|
|
|
- List<Double> oldUserData = new ArrayList<>();
|
|
|
- for (int i = 0; i < dataSize; i++) {
|
|
|
- double value = activeData.get(i) - newUserData.get(i);
|
|
|
- oldUserData.add(value); // 直接为Double类型
|
|
|
- }
|
|
|
-// oldUser.setData(oldUserData);
|
|
|
- items.add(oldUser);
|
|
|
-
|
|
|
+ GetActiveUserBaseVO result = new GetActiveUserBaseVO();
|
|
|
+ result.setDates(dates);
|
|
|
result.setItems(items);
|
|
|
return result;
|
|
|
}
|
|
@@ -436,13 +424,16 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
*/
|
|
|
@Override
|
|
|
public GetActiveUserBaseVO getActiveViscosity(UserAnalyseQueryBaseDTO reqDto) {
|
|
|
+ // 1. 时间单位校验
|
|
|
if (!"day".equals(reqDto.getTimeUnit())){
|
|
|
throw new BusinessException("时间单位只能为day");
|
|
|
}
|
|
|
+ // 2. 获取版本
|
|
|
String version = null;
|
|
|
if (reqDto.getVersion() != null && !reqDto.getVersion().isEmpty()) {
|
|
|
version =reqDto.getVersion().get(0);
|
|
|
}
|
|
|
+ // 3. 定义相关变量
|
|
|
List<ActiveUserComposeVO> items = new ArrayList<>();
|
|
|
|
|
|
List<BigDecimal> dayCounts = new ArrayList<>();
|
|
@@ -450,32 +441,34 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
List<BigDecimal> thirtyCounts = new ArrayList<>();
|
|
|
List<BigDecimal> sevenRates = new ArrayList<>();
|
|
|
List<BigDecimal> thirtyRates = new ArrayList<>();
|
|
|
-
|
|
|
+ // 4. 获取时间坐标轴
|
|
|
List<String> dates = generateTimeAxis(reqDto.getFromDate(), reqDto.getToDate(), reqDto.getTimeUnit());
|
|
|
+ // 5. 遍历时间坐标轴
|
|
|
for (String date : dates) {
|
|
|
+ // 5.1 定义时间范围
|
|
|
LocalDateTime startTime = getStartTime(date, reqDto.getTimeUnit());
|
|
|
LocalDateTime endTime = getEndTime(date, reqDto.getTimeUnit());
|
|
|
LocalDateTime sevenDaysAgo = startTime.minusDays(7);
|
|
|
LocalDateTime thirtyDaysAgo = startTime.minusDays(30);
|
|
|
- // 今日活跃用户数
|
|
|
+ // 5.2 今日活跃用户数
|
|
|
BigDecimal dayCount = BigDecimal.valueOf(statActiveUserCount(startTime, endTime, reqDto.getAppId(), version, reqDto.getChannel()));
|
|
|
dayCounts.add(dayCount);
|
|
|
- // 过去7日活跃用户
|
|
|
+ // 5.3 过去7日活跃用户
|
|
|
BigDecimal sevenCount = BigDecimal.valueOf(statActiveUserCount(sevenDaysAgo, startTime, reqDto.getAppId(), version, reqDto.getChannel()));
|
|
|
sevenCounts.add(sevenCount);
|
|
|
- // 过去7日活跃用户
|
|
|
+ // 5.4 过去30日活跃用户
|
|
|
BigDecimal thirtyCount = BigDecimal.valueOf(statActiveUserCount(thirtyDaysAgo, startTime, reqDto.getAppId(), version, reqDto.getChannel()));
|
|
|
thirtyCounts.add(thirtyCount);
|
|
|
- // 计算7日活跃用户占比
|
|
|
+ // 5.5 计算7日活跃用户占比
|
|
|
sevenRates.add(dayCount.compareTo(BigDecimal.ZERO) == 0 || sevenCount.compareTo(BigDecimal.ZERO) == 0
|
|
|
? BigDecimal.ZERO
|
|
|
: dayCount.divide(sevenCount, 4, RoundingMode.HALF_UP));
|
|
|
- // 计算30日活跃用户占比
|
|
|
+ // 5.6 计算30日活跃用户占比
|
|
|
thirtyRates.add(dayCount.compareTo(BigDecimal.ZERO) == 0 || thirtyCount.compareTo(BigDecimal.ZERO) == 0
|
|
|
? BigDecimal.ZERO:
|
|
|
dayCount.divide(thirtyCount, 4, RoundingMode.HALF_UP));
|
|
|
}
|
|
|
- // 组装返回数据
|
|
|
+ // 6. 组装返回数据
|
|
|
ActiveUserComposeVO activeUser = new ActiveUserComposeVO();
|
|
|
activeUser.setData(dayCounts);
|
|
|
activeUser.setName("日活");
|
|
@@ -511,6 +504,7 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
mauRate.setVersion(version == null ? "All" : version);
|
|
|
items.add(mauRate);
|
|
|
|
|
|
+ // 7.返回结果
|
|
|
GetActiveUserBaseVO result = new GetActiveUserBaseVO();
|
|
|
result.setDates(dates);
|
|
|
result.setItems(items);
|
|
@@ -523,7 +517,57 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
* @return GetActiveUserBaseVO
|
|
|
*/
|
|
|
@Override
|
|
|
- public GetActiveUserBaseVO getActiveWeekrate(UserAnalyseQueryBaseDTO reqDto) {
|
|
|
+ public GetActiveUserBaseVO getActiveWeekRate(UserAnalyseQueryBaseDTO reqDto) {
|
|
|
+ if (!"week".equals(reqDto.getTimeUnit())){
|
|
|
+ throw new BusinessException("时间单位只能为week");
|
|
|
+ }
|
|
|
+ // 1. 生成时间轴
|
|
|
+ List<String> dates = generateTimeAxis(reqDto.getFromDate(), reqDto.getToDate(), reqDto.getTimeUnit());
|
|
|
+ // 2. 定义存储列表
|
|
|
+ List<BigDecimal> activeList = new ArrayList<>();
|
|
|
+ List<BigDecimal> userList = new ArrayList<>();
|
|
|
+ List<BigDecimal> weekRateList = new ArrayList<>();
|
|
|
+ // 3. 遍历时间轴
|
|
|
+ for (String date : dates) {
|
|
|
+ LocalDateTime startTime = getStartTime(date, reqDto.getTimeUnit());
|
|
|
+ LocalDateTime endTime = getEndTime(date, reqDto.getTimeUnit());
|
|
|
+ // 4. 查询、计算累计用户数
|
|
|
+ BigDecimal totalUser = BigDecimal.valueOf(statNewUserCount(null, endTime, reqDto.getAppId(), null, null));
|
|
|
+ userList.add(totalUser);
|
|
|
+ // 5. 查询、计算本周活跃用户数
|
|
|
+ BigDecimal activeUser = BigDecimal.valueOf(statActiveUserCount(startTime, endTime, reqDto.getAppId(), null, null));
|
|
|
+ activeList.add(activeUser);
|
|
|
+ // 6. 计算周活跃率
|
|
|
+ BigDecimal weekRate = totalUser.compareTo(BigDecimal.ZERO) != 0 && activeUser.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? activeUser.divide(totalUser, 4, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO;
|
|
|
+ weekRateList.add(weekRate);
|
|
|
+ }
|
|
|
+ // 7. 组装结果数据
|
|
|
+ ActiveUserComposeVO totalUser = new ActiveUserComposeVO();
|
|
|
+ totalUser.setName("周累积用户");
|
|
|
+ totalUser.setKey("weekTotalUser");
|
|
|
+ totalUser.setVersion("All");
|
|
|
+ totalUser.setData(userList);
|
|
|
+
|
|
|
+ ActiveUserComposeVO activeUser = new ActiveUserComposeVO();
|
|
|
+ activeUser.setName("周活跃用户");
|
|
|
+ activeUser.setKey("weekActiveUser");
|
|
|
+ activeUser.setVersion("All");
|
|
|
+ activeUser.setData(activeList);
|
|
|
+
|
|
|
+ ActiveUserComposeVO weekRate = new ActiveUserComposeVO();
|
|
|
+ weekRate.setName("周活跃用户率");
|
|
|
+ weekRate.setKey("weekActiveUserRate");
|
|
|
+ weekRate.setVersion("All");
|
|
|
+ weekRate.setData(weekRateList);
|
|
|
+ // 8. 返回结果
|
|
|
+ GetActiveUserBaseVO result = new GetActiveUserBaseVO();
|
|
|
+ result.setDates(dates);
|
|
|
+ result.setItems(Arrays.asList(totalUser, activeUser, weekRate));
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ public GetActiveUserBaseVO getActiveWeekrate2(UserAnalyseQueryBaseDTO reqDto) {
|
|
|
if (!"week".equals(reqDto.getTimeUnit())){
|
|
|
throw new BusinessException("时间单位错误");
|
|
|
}
|
|
@@ -585,7 +629,58 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
* @return GetActiveUserBaseVO
|
|
|
*/
|
|
|
@Override
|
|
|
- public GetActiveUserBaseVO getActiveMonthrate(UserAnalyseQueryBaseDTO reqDto) {
|
|
|
+ public GetActiveUserBaseVO getActiveMonthRate(UserAnalyseQueryBaseDTO reqDto) {
|
|
|
+ if (!"month".equals(reqDto.getTimeUnit())){
|
|
|
+ throw new BusinessException("时间单位只能为month");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1. 生成时间轴
|
|
|
+ List<String> dates = generateTimeAxis(reqDto.getFromDate(), reqDto.getToDate(), reqDto.getTimeUnit());
|
|
|
+ // 2. 定义存储列表
|
|
|
+ List<BigDecimal> activeList = new ArrayList<>();
|
|
|
+ List<BigDecimal> userList = new ArrayList<>();
|
|
|
+ List<BigDecimal> monthRateList = new ArrayList<>();
|
|
|
+ // 3. 遍历时间轴
|
|
|
+ for (String date : dates) {
|
|
|
+ LocalDateTime startTime = getStartTime(date, reqDto.getTimeUnit());
|
|
|
+ LocalDateTime endTime = getEndTime(date, reqDto.getTimeUnit());
|
|
|
+ // 4. 查询、计算累计用户数
|
|
|
+ BigDecimal totalUser = BigDecimal.valueOf(statNewUserCount(null, endTime, reqDto.getAppId(), null, null));
|
|
|
+ userList.add(totalUser);
|
|
|
+ // 5. 查询、计算本月活跃用户数
|
|
|
+ BigDecimal activeUser = BigDecimal.valueOf(statActiveUserCount(startTime, endTime, reqDto.getAppId(), null, null));
|
|
|
+ activeList.add(activeUser);
|
|
|
+ // 6. 计算月活跃率
|
|
|
+ BigDecimal weekRate = totalUser.compareTo(BigDecimal.ZERO) != 0 && activeUser.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? activeUser.divide(totalUser, 4, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO;
|
|
|
+ monthRateList.add(weekRate);
|
|
|
+ }
|
|
|
+ // 7. 组装结果数据
|
|
|
+ ActiveUserComposeVO totalUser = new ActiveUserComposeVO();
|
|
|
+ totalUser.setName("月累积用户");
|
|
|
+ totalUser.setKey("monthTotalUser");
|
|
|
+ totalUser.setVersion("All");
|
|
|
+ totalUser.setData(userList);
|
|
|
+
|
|
|
+ ActiveUserComposeVO activeUser = new ActiveUserComposeVO();
|
|
|
+ activeUser.setName("月活跃用户");
|
|
|
+ activeUser.setKey("monthActiveUser");
|
|
|
+ activeUser.setVersion("All");
|
|
|
+ activeUser.setData(activeList);
|
|
|
+
|
|
|
+ ActiveUserComposeVO monthRate = new ActiveUserComposeVO();
|
|
|
+ monthRate.setName("月活跃用户率");
|
|
|
+ monthRate.setKey("monthActiveUserRate");
|
|
|
+ monthRate.setVersion("All");
|
|
|
+ monthRate.setData(monthRateList);
|
|
|
+ // 8. 返回结果
|
|
|
+ GetActiveUserBaseVO result = new GetActiveUserBaseVO();
|
|
|
+ result.setDates(dates);
|
|
|
+ result.setItems(Arrays.asList(totalUser, activeUser, monthRate));
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ public GetActiveUserBaseVO getActiveMonthRate2(UserAnalyseQueryBaseDTO reqDto) {
|
|
|
if (!"month".equals(reqDto.getTimeUnit())){
|
|
|
throw new BusinessException("时间单位错误");
|
|
|
}
|
|
@@ -801,6 +896,90 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
page.setRecords( result);
|
|
|
return page;
|
|
|
}
|
|
|
+// public Page<PageActiveDetailVO> pageActiveDetail(PageActiveDetailDTO reqDto) {
|
|
|
+// // 1. 初始化分页对象并计算总条数
|
|
|
+// Page<PageActiveDetailVO> page = new Page<>(reqDto.getCurrent(), reqDto.getSize());
|
|
|
+// page.setTotal(calculateTotalCount(reqDto.getFromDate(), reqDto.getToDate(), reqDto.getTimeUnit()));
|
|
|
+//
|
|
|
+// // 2. 生成当前页时间轴
|
|
|
+// List<String> dates = generatePageTimeAxis(reqDto.getFromDate(), reqDto.getToDate(),
|
|
|
+// reqDto.getTimeUnit(), reqDto.getCurrent(), reqDto.getSize());
|
|
|
+// if (dates.isEmpty()) {
|
|
|
+// return page; // 无数据直接返回
|
|
|
+// }
|
|
|
+// // 获取渠道和版本
|
|
|
+// List<String> channel = reqDto.getChannel();
|
|
|
+// String version = null;
|
|
|
+// if (reqDto.getVersion() != null && !reqDto.getVersion().isEmpty()){
|
|
|
+// version = reqDto.getVersion().get(0);
|
|
|
+// }
|
|
|
+// // 查询结果
|
|
|
+// List<PageActiveDetailVO> result = new ArrayList<>();
|
|
|
+// for (String date : dates) {
|
|
|
+// PageActiveDetailVO detail = new PageActiveDetailVO();
|
|
|
+// LocalDateTime startTime = getStartTime(date, reqDto.getTimeUnit());
|
|
|
+// LocalDateTime endTime = getEndTime(date, reqDto.getTimeUnit());
|
|
|
+//
|
|
|
+// // 查询活跃用户数量
|
|
|
+// BigDecimal activeCount = BigDecimal.valueOf(statActiveUserCount(startTime, endTime, reqDto.getAppId(), version, reqDto.getChannel()));
|
|
|
+// // 查询活跃用户中的新增用户数
|
|
|
+// BigDecimal newCount = BigDecimal.valueOf(getActiveNewUserCount(startTime, endTime, reqDto.getAppId(), version, reqDto.getChannel()));
|
|
|
+// // 计算新增用户占比
|
|
|
+// BigDecimal newUserRate = activeCount.compareTo(BigDecimal.ZERO) == 0 || newCount.compareTo(BigDecimal.ZERO) == 0 ?
|
|
|
+// BigDecimal.ZERO :
|
|
|
+// newCount.divide(activeCount, 4, RoundingMode.HALF_UP);
|
|
|
+//
|
|
|
+// if("day".equals(reqDto.getTimeUnit())){
|
|
|
+// LocalDateTime sevenDaysAgo = startTime.minusDays(7);
|
|
|
+// LocalDateTime thirtyDaysAgo = startTime.minusDays(30);
|
|
|
+// // 查询过去7天活跃用户数量
|
|
|
+// BigDecimal sevenCount = BigDecimal.valueOf(statActiveUserCount(sevenDaysAgo, startTime, reqDto.getAppId(), version, reqDto.getChannel()));
|
|
|
+// // 查询过去30天活跃用户数量
|
|
|
+// BigDecimal thirtyCount = BigDecimal.valueOf(statActiveUserCount(thirtyDaysAgo, startTime, reqDto.getAppId(), version, reqDto.getChannel()));
|
|
|
+//
|
|
|
+// // 计算用户周活跃率
|
|
|
+// BigDecimal wauRate = sevenCount.compareTo(BigDecimal.ZERO) != 0 && activeCount.compareTo(BigDecimal.ZERO) != 0
|
|
|
+// ? activeCount.divide(sevenCount, 4, RoundingMode.HALF_UP)
|
|
|
+// : BigDecimal.ZERO;
|
|
|
+//
|
|
|
+// // 计算
|
|
|
+// }
|
|
|
+//
|
|
|
+//
|
|
|
+//
|
|
|
+// // 过去30日活跃用户
|
|
|
+// List<MktStatUserAnalysis> thirtyDaysUser = userAnalysisMapper.selectList(Wrappers.<MktStatUserAnalysis>lambdaQuery()
|
|
|
+// .ge(MktStatUserAnalysis::getStatDate, thirtyDaysAgo)
|
|
|
+// .lt(MktStatUserAnalysis::getStatDate, startTime)
|
|
|
+// .in(channel!=null && !channel.isEmpty(),MktStatUserAnalysis::getChannel, channel)
|
|
|
+// .eq("All".equals(version),MktStatUserAnalysis::getVersion, version)
|
|
|
+// .select(MktStatUserAnalysis::getNewUser, MktStatUserAnalysis::getActiveUser)
|
|
|
+// );
|
|
|
+// BigDecimal thirtyDaysActiveUser = BigDecimal.valueOf(thirtyDaysUser.stream()
|
|
|
+// .mapToInt(MktStatUserAnalysis::getActiveUser)
|
|
|
+// .sum());
|
|
|
+// BigDecimal thirtyDaysNewUser = BigDecimal.valueOf(thirtyDaysUser.stream()
|
|
|
+// .mapToInt(MktStatUserAnalysis::getNewUser)
|
|
|
+// .sum());
|
|
|
+// BigDecimal mauRate = thirtyDaysActiveUser.compareTo(BigDecimal.ZERO) != 0 && thirtyDaysNewUser.compareTo(BigDecimal.ZERO) != 0
|
|
|
+// ? thirtyDaysNewUser.divide(thirtyDaysActiveUser, 4, RoundingMode.HALF_UP)
|
|
|
+// : BigDecimal.ZERO;
|
|
|
+//
|
|
|
+//
|
|
|
+// detail.setDate(date);
|
|
|
+// detail.setActiveUser(activeUser.intValue());
|
|
|
+// detail.setNewUserRate(newUserRate);
|
|
|
+// detail.setWauRate(wauRate);
|
|
|
+// detail.setMauRate(mauRate);
|
|
|
+// result.add(detail);
|
|
|
+//
|
|
|
+//
|
|
|
+// }
|
|
|
+//
|
|
|
+//
|
|
|
+//
|
|
|
+// return page;
|
|
|
+// }
|
|
|
|
|
|
/************************************** 启动次数 *****************************************
|
|
|
* 查询启动次数趋势
|
|
@@ -833,7 +1012,7 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
.map(date -> calculateNewUserCount(date, version, reqDto.getChannel(), reqDto.getTimeUnit(), "launch"))
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
- trend.setData(counts);
|
|
|
+// trend.setData(counts);
|
|
|
return trend;
|
|
|
})
|
|
|
.collect(Collectors.toList());
|
|
@@ -1508,26 +1687,7 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
* 统计指定时间范围内的新增用户数
|
|
|
*/
|
|
|
private Long statNewUserCount(LocalDateTime startTime, LocalDateTime endTime, String appId, String version, List<String> channels){
|
|
|
- // 1. 空值判断
|
|
|
- if (startTime == null || endTime == null) {
|
|
|
- return 0L;
|
|
|
- }
|
|
|
- // 2. 组装查询条件
|
|
|
- LambdaQueryWrapper<MktStatNewUser> queryWrapper = Wrappers.<MktStatNewUser>lambdaQuery()
|
|
|
- .eq(MktStatNewUser::getAppId, appId)
|
|
|
- .ge(MktStatNewUser::getStatDate, startTime)
|
|
|
- .lt(MktStatNewUser::getStatDate, endTime);
|
|
|
-
|
|
|
- // 添加渠道条件
|
|
|
- if (channels != null && !channels.isEmpty()) {
|
|
|
- queryWrapper.in(MktStatNewUser::getChannel, channels);
|
|
|
- }
|
|
|
- // 添加版本条件
|
|
|
- if (version != null && !version.isEmpty()){
|
|
|
- queryWrapper.eq(MktStatNewUser::getVersion, version);
|
|
|
- }
|
|
|
- // 3. 统计新增用户数,不用去重
|
|
|
- List<MktStatNewUser> newUsers = newUserMapper.selectList(queryWrapper);
|
|
|
+ List<String> newUsers = getNewUserIdList(startTime, endTime, appId, version, channels);
|
|
|
return newUsers == null ? 0L : newUsers.size();
|
|
|
}
|
|
|
|
|
@@ -1535,28 +1695,81 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
* 统计指定时间范围内的活跃用户数(去重)
|
|
|
*/
|
|
|
private Long statActiveUserCount(LocalDateTime startTime, LocalDateTime endTime, String appId, String version, List<String> channels){
|
|
|
- // 1. 空值判断
|
|
|
- if (startTime == null || endTime == null) {
|
|
|
- return 0L;
|
|
|
- }
|
|
|
- // 2. 组装查询条件
|
|
|
+ List<String> activeUsers = getActiveUserIdList(startTime, endTime, appId, version, channels);
|
|
|
+ return activeUsers == null ? 0L : activeUsers.size();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询指定时间范围内的活跃用户Id列表(去重)
|
|
|
+ */
|
|
|
+ private List<String> getActiveUserIdList(LocalDateTime startTime, LocalDateTime endTime, String appId, String version, List<String> channels){
|
|
|
+ // 1. 组装查询条件
|
|
|
LambdaQueryWrapper<MktStatActiveUser> queryWrapper = Wrappers.<MktStatActiveUser>lambdaQuery()
|
|
|
.eq(MktStatActiveUser::getAppId, appId)
|
|
|
- .ge(MktStatActiveUser::getStatDate, startTime)
|
|
|
- .lt(MktStatActiveUser::getStatDate, endTime)
|
|
|
+ .ge(startTime != null, MktStatActiveUser::getStatDate, startTime)
|
|
|
+ .lt(endTime != null, MktStatActiveUser::getStatDate, endTime)
|
|
|
.select(MktStatActiveUser::getUserId)
|
|
|
.groupBy(MktStatActiveUser::getUserId);
|
|
|
|
|
|
- // 添加渠道条件
|
|
|
+ // 2. 添加渠道条件
|
|
|
if (channels != null && !channels.isEmpty()) {
|
|
|
queryWrapper.in(MktStatActiveUser::getChannel, channels);
|
|
|
}
|
|
|
- // 添加版本条件
|
|
|
+ // 3. 添加版本条件
|
|
|
if (version != null && !version.isEmpty()){
|
|
|
queryWrapper.eq(MktStatActiveUser::getVersion, version);
|
|
|
}
|
|
|
- // 3. 统计活跃用户数,根据userID去重
|
|
|
+ // 4. 统计活跃用户数,根据userID去重
|
|
|
List<MktStatActiveUser> activeUsers = activeUserMapper.selectList(queryWrapper);
|
|
|
- return activeUsers == null ? 0L : activeUsers.size();
|
|
|
+ return activeUsers.stream().map(MktStatActiveUser::getUserId).toList();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询指定时间范围内的活跃用户Id列表(去重)
|
|
|
+ */
|
|
|
+ private List<String> getNewUserIdList(LocalDateTime startTime, LocalDateTime endTime, String appId, String version, List<String> channels){
|
|
|
+
|
|
|
+ // 1. 组装查询条件
|
|
|
+ LambdaQueryWrapper<MktStatNewUser> queryWrapper = Wrappers.<MktStatNewUser>lambdaQuery()
|
|
|
+ .eq(MktStatNewUser::getAppId, appId)
|
|
|
+ .ge(startTime != null ,MktStatNewUser::getStatDate, startTime)
|
|
|
+ .lt(endTime != null ,MktStatNewUser::getStatDate, endTime);
|
|
|
+
|
|
|
+ // 2. 添加渠道条件
|
|
|
+ if (channels != null && !channels.isEmpty()) {
|
|
|
+ queryWrapper.in(MktStatNewUser::getChannel, channels);
|
|
|
+ }
|
|
|
+ // 3. 添加版本条件
|
|
|
+ if (version != null && !version.isEmpty()){
|
|
|
+ queryWrapper.eq(MktStatNewUser::getVersion, version);
|
|
|
+ }
|
|
|
+ // 4. 统计新增用户数,不用去重
|
|
|
+ List<MktStatNewUser> newUsers = newUserMapper.selectList(queryWrapper);
|
|
|
+ return newUsers.stream().map(MktStatNewUser::getUserId).toList();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取活跃用户中新增用户的数量
|
|
|
+ */
|
|
|
+ private Long getActiveNewUserCount(LocalDateTime startTime, LocalDateTime endTime, String appId, String version, List<String> channels) {
|
|
|
+ // 1. 获取活跃用户ID列表
|
|
|
+ List<String> activeUserIds = getActiveUserIdList(startTime, endTime, appId, version, channels);
|
|
|
+ if (activeUserIds == null || activeUserIds.isEmpty()) {
|
|
|
+ return 0L;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 获取新增用户ID列表
|
|
|
+ List<String> newUserIds = getNewUserIdList(startTime, endTime, appId, version, channels);
|
|
|
+ if (newUserIds == null || newUserIds.isEmpty()) {
|
|
|
+ return 0L;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 计算交集:既是活跃用户又是新增用户的用户数量
|
|
|
+ Set<String> activeUserSet = new HashSet<>(activeUserIds);
|
|
|
+ Set<String> newUserSet = new HashSet<>(newUserIds);
|
|
|
+
|
|
|
+ // 4. 保留在活跃用户集合中的新增用户
|
|
|
+ activeUserSet.retainAll(newUserSet);
|
|
|
+ return (long) activeUserSet.size();
|
|
|
}
|
|
|
}
|