|
@@ -4,6 +4,7 @@ package com.pig4cloud.pig.statistics.service.impl;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.pig4cloud.pig.common.core.exception.BusinessException;
|
|
|
import com.pig4cloud.pig.statistics.api.dto.user.*;
|
|
|
import com.pig4cloud.pig.statistics.api.entity.MktStatUserAnalysis;
|
|
|
import com.pig4cloud.pig.statistics.api.entity.MktStatUserRetention;
|
|
@@ -72,7 +73,7 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
|
|
|
// 计算每个时间点的新增用户数
|
|
|
List<Integer> counts = dates.stream()
|
|
|
- .map(date -> calculateNewUserCount(date, version, reqDto, "newUser"))
|
|
|
+ .map(date -> calculateNewUserCount(date, version, reqDto.getChannel(), reqDto.getTimeUnit(), "newUser"))
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
trend.setData(counts);
|
|
@@ -298,7 +299,7 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
|
|
|
// 计算每个时间点的活跃用户数
|
|
|
List<Integer> counts = dates.stream()
|
|
|
- .map(date -> calculateNewUserCount(date, version, reqDto, "activeUser"))
|
|
|
+ .map(date -> calculateNewUserCount(date, version, reqDto.getChannel(), reqDto.getTimeUnit(), "activeUser"))
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
trend.setData(counts);
|
|
@@ -380,7 +381,7 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
int value = 30000 + random.nextInt(5000) + (i * 50);
|
|
|
activeData.add((double) value); // 整数转Double
|
|
|
}
|
|
|
- activeUser.setData(activeData);
|
|
|
+// activeUser.setData(activeData);
|
|
|
items.add(activeUser);
|
|
|
|
|
|
// 新增用户数据(整数转为Double)
|
|
@@ -391,7 +392,7 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
int value = activeData.get(i).intValue() - 100 - random.nextInt(300);
|
|
|
newUserData.add((double) value); // 整数转Double
|
|
|
}
|
|
|
- newUser.setData(newUserData);
|
|
|
+// newUser.setData(newUserData);
|
|
|
items.add(newUser);
|
|
|
|
|
|
// 新增用户占比数据(保持Double类型)
|
|
@@ -402,7 +403,7 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
double rate = (newUserData.get(i) / activeData.get(i)) * 100;
|
|
|
rateData.add(Math.round(rate * 100) / 100.0); // 保留两位小数
|
|
|
}
|
|
|
- newUserRate.setData(rateData);
|
|
|
+// newUserRate.setData(rateData);
|
|
|
items.add(newUserRate);
|
|
|
|
|
|
// 老用户数据(计算后转为Double)
|
|
@@ -413,7 +414,7 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
double value = activeData.get(i) - newUserData.get(i);
|
|
|
oldUserData.add(value); // 直接为Double类型
|
|
|
}
|
|
|
- oldUser.setData(oldUserData);
|
|
|
+// oldUser.setData(oldUserData);
|
|
|
items.add(oldUser);
|
|
|
|
|
|
result.setItems(items);
|
|
@@ -443,31 +444,31 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
// 日活数据
|
|
|
ActiveUserComposeVO activeUserItem = new ActiveUserComposeVO();
|
|
|
activeUserItem.setName("日活");
|
|
|
- activeUserItem.setData(Arrays.asList(1523.0, 1489.0, 1602.0, 1576.0, 987.0, 923.0, 1756.0, 1632.0));
|
|
|
+// activeUserItem.setData(Arrays.asList(1523.0, 1489.0, 1602.0, 1576.0, 987.0, 923.0, 1756.0, 1632.0));
|
|
|
items.add(activeUserItem);
|
|
|
|
|
|
// 过去7日活跃用户数据
|
|
|
ActiveUserComposeVO wauItem = new ActiveUserComposeVO();
|
|
|
wauItem.setName("过去7日活跃用户");
|
|
|
- wauItem.setData(Arrays.asList(8234.0, 8156.0, 8321.0, 8289.0, 8356.0, 8412.0, 8531.0, 8498.0));
|
|
|
+// wauItem.setData(Arrays.asList(8234.0, 8156.0, 8321.0, 8289.0, 8356.0, 8412.0, 8531.0, 8498.0));
|
|
|
items.add(wauItem);
|
|
|
|
|
|
// DAU/过去7日活跃用户比率
|
|
|
ActiveUserComposeVO wauRateItem = new ActiveUserComposeVO();
|
|
|
wauRateItem.setName("DAU/过去7日活跃用户");
|
|
|
- wauRateItem.setData(Arrays.asList(18.5, 18.25, 19.25, 19.01, 11.81, 10.97, 20.58, 19.21));
|
|
|
+// wauRateItem.setData(Arrays.asList(18.5, 18.25, 19.25, 19.01, 11.81, 10.97, 20.58, 19.21));
|
|
|
items.add(wauRateItem);
|
|
|
|
|
|
// 过去30日活跃用户数据
|
|
|
ActiveUserComposeVO mauItem = new ActiveUserComposeVO();
|
|
|
mauItem.setName("过去30日活跃用户");
|
|
|
- mauItem.setData(Arrays.asList(35621.0, 35489.0, 35723.0, 35698.0, 34987.0, 34215.0, 35123.0, 36012.0));
|
|
|
+// mauItem.setData(Arrays.asList(35621.0, 35489.0, 35723.0, 35698.0, 34987.0, 34215.0, 35123.0, 36012.0));
|
|
|
items.add(mauItem);
|
|
|
|
|
|
// DAU/过去30日活跃用户比率
|
|
|
ActiveUserComposeVO mauRateItem = new ActiveUserComposeVO();
|
|
|
mauRateItem.setName("DAU/过去30日活跃用户");
|
|
|
- mauRateItem.setData(Arrays.asList(4.28, 4.19, 4.48, 4.42, 2.82, 2.70, 5.00, 4.53));
|
|
|
+// mauRateItem.setData(Arrays.asList(4.28, 4.19, 4.48, 4.42, 2.82, 2.70, 5.00, 4.53));
|
|
|
items.add(mauRateItem);
|
|
|
|
|
|
result.setItems(items);
|
|
@@ -481,72 +482,61 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
*/
|
|
|
@Override
|
|
|
public GetActiveUserBaseVO getActiveWeekrate(UserAnalyseQueryBaseDTO reqDto) {
|
|
|
- GetActiveUserBaseVO result = new GetActiveUserBaseVO();
|
|
|
- Random random = new Random();
|
|
|
- DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
-
|
|
|
- // 1. 生成周日期列表(每周一)
|
|
|
- List<String> dates = new ArrayList<>();
|
|
|
- LocalDate currentDate = reqDto.getFromDate();
|
|
|
- // 调整到当周周一
|
|
|
- currentDate = currentDate.minusDays(currentDate.getDayOfWeek().getValue() - 1);
|
|
|
-
|
|
|
- while (!currentDate.isAfter(reqDto.getToDate())) {
|
|
|
- dates.add(currentDate.format(dateFormatter));
|
|
|
- currentDate = currentDate.plusWeeks(1);
|
|
|
+ if (!"week".equals(reqDto.getTimeUnit())){
|
|
|
+ throw new BusinessException("时间单位错误");
|
|
|
}
|
|
|
+ reqDto.setChannel( null);
|
|
|
+ reqDto.setVersion( null);
|
|
|
+ GetActiveUserBaseVO result = new GetActiveUserBaseVO();
|
|
|
+ // 1. 生成时间轴
|
|
|
+ List<String> dates = generateTimeAxis(reqDto.getFromDate(), reqDto.getToDate(), reqDto.getTimeUnit());
|
|
|
result.setDates(dates);
|
|
|
- int dataSize = dates.size();
|
|
|
-
|
|
|
- // 2. 生成周累积用户数据(240万起,每周递增0.2%-0.4%)
|
|
|
- List<Double> weekTotalUserList = new ArrayList<>();
|
|
|
- double baseTotal = 2400000;
|
|
|
- for (int i = 0; i < dataSize; i++) {
|
|
|
- baseTotal += baseTotal * (0.002 + random.nextDouble() * 0.002);
|
|
|
- // 四舍五入取整(内部实现四舍五入逻辑)
|
|
|
- weekTotalUserList.add((double) Math.round(baseTotal));
|
|
|
- }
|
|
|
-
|
|
|
- // 3. 生成周活跃用户数据(周累积的0.28%-0.33%)
|
|
|
- List<Double> weekActiveUserList = new ArrayList<>();
|
|
|
- for (double total : weekTotalUserList) {
|
|
|
- double active = total * (0.0028 + random.nextDouble() * 0.0005);
|
|
|
- weekActiveUserList.add((double) Math.round(active)); // 四舍五入取整
|
|
|
- }
|
|
|
-
|
|
|
- // 4. 生成周活跃用户率(保留两位小数)
|
|
|
- List<Double> weekActiveRateList = new ArrayList<>();
|
|
|
- for (int i = 0; i < dataSize; i++) {
|
|
|
- double rate = (weekActiveUserList.get(i) / weekTotalUserList.get(i)) * 100;
|
|
|
- // 四舍五入保留两位小数:先乘100取整再除以100
|
|
|
- weekActiveRateList.add(Math.round(rate * 100) / 100.0);
|
|
|
+ // 2. 定义存储列表
|
|
|
+ List<BigDecimal> activeList = new ArrayList<>();
|
|
|
+ List<BigDecimal> userList = new ArrayList<>();
|
|
|
+ List<BigDecimal> weekRateList = new ArrayList<>();
|
|
|
+ // 3. 遍历时间轴
|
|
|
+ for (String date : dates) {
|
|
|
+ LocalDateTime endTime = getEndTime(date, reqDto.getTimeUnit());
|
|
|
+ // 4. 查询、计算累计用户数
|
|
|
+ List<MktStatUserAnalysis> userAnalyses = userAnalysisMapper.selectList(Wrappers.<MktStatUserAnalysis>lambdaQuery()
|
|
|
+ .lt(MktStatUserAnalysis::getStatDate, endTime)
|
|
|
+ .select(MktStatUserAnalysis::getNewUser)
|
|
|
+ );
|
|
|
+ BigDecimal totalUser = BigDecimal.valueOf(userAnalyses.stream()
|
|
|
+ .mapToInt(MktStatUserAnalysis::getNewUser)
|
|
|
+ .sum());
|
|
|
+ userList.add(totalUser);
|
|
|
+ // 5. 查询、计算本周活跃用户数
|
|
|
+ BigDecimal activeUser = BigDecimal.valueOf(calculateNewUserCount(date, "All", reqDto.getChannel(), reqDto.getTimeUnit(), "activeUser"));
|
|
|
+ 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);
|
|
|
|
|
|
- // 5. 组装返回数据
|
|
|
- List<ActiveUserComposeVO> items = new ArrayList<>();
|
|
|
-
|
|
|
- // 周累积用户
|
|
|
- ActiveUserComposeVO totalItem = new ActiveUserComposeVO();
|
|
|
- totalItem.setName("周累积用户");
|
|
|
- totalItem.setData(weekTotalUserList);
|
|
|
- items.add(totalItem);
|
|
|
-
|
|
|
- // 周活跃用户
|
|
|
- ActiveUserComposeVO activeItem = new ActiveUserComposeVO();
|
|
|
- activeItem.setName("周活跃用户");
|
|
|
- activeItem.setData(weekActiveUserList);
|
|
|
- items.add(activeItem);
|
|
|
-
|
|
|
- // 周活跃用户率
|
|
|
- ActiveUserComposeVO rateItem = new ActiveUserComposeVO();
|
|
|
- rateItem.setName("周活跃用户率");
|
|
|
- rateItem.setData(weekActiveRateList);
|
|
|
- items.add(rateItem);
|
|
|
-
|
|
|
- result.setItems(items);
|
|
|
+ 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);
|
|
|
+ result.setItems(Arrays.asList(totalUser, activeUser, weekRate));
|
|
|
return result;
|
|
|
}
|
|
|
-
|
|
|
/**
|
|
|
* 获取月活跃率
|
|
|
* @param reqDto 获取月活跃率入参
|
|
@@ -554,72 +544,59 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
*/
|
|
|
@Override
|
|
|
public GetActiveUserBaseVO getActiveMonthrate(UserAnalyseQueryBaseDTO reqDto) {
|
|
|
- // 创建返回对象
|
|
|
- GetActiveUserBaseVO result = new GetActiveUserBaseVO();
|
|
|
- Random random = new Random();
|
|
|
- DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
-
|
|
|
- // 1. 生成月日期列表(每月1日)
|
|
|
- List<String> dates = new ArrayList<>();
|
|
|
- LocalDate currentDate = reqDto.getFromDate();
|
|
|
-
|
|
|
- // 调整到当月1日
|
|
|
- currentDate = currentDate.withDayOfMonth(1);
|
|
|
-
|
|
|
- // 按月生成日期直到结束日期
|
|
|
- while (!currentDate.isAfter(reqDto.getToDate())) {
|
|
|
- dates.add(currentDate.format(dateFormatter));
|
|
|
- currentDate = currentDate.plusMonths(1);
|
|
|
+ if (!"month".equals(reqDto.getTimeUnit())){
|
|
|
+ throw new BusinessException("时间单位错误");
|
|
|
}
|
|
|
+ reqDto.setChannel( null);
|
|
|
+ reqDto.setVersion( null);
|
|
|
+ GetActiveUserBaseVO result = new GetActiveUserBaseVO();
|
|
|
+ // 1. 生成时间轴
|
|
|
+ List<String> dates = generateTimeAxis(reqDto.getFromDate(), reqDto.getToDate(), reqDto.getTimeUnit());
|
|
|
result.setDates(dates);
|
|
|
- int dataSize = dates.size();
|
|
|
-
|
|
|
- // 2. 生成月累积用户数据(基础值250万,每月递增约1.2%-1.8%)
|
|
|
- List<Double> monthTotalUserList = new ArrayList<>();
|
|
|
- double baseTotal = 2500000; // 基础用户量
|
|
|
- for (int i = 0; i < dataSize; i++) {
|
|
|
- // 每月增加1.2%-1.8%的随机增长
|
|
|
- double growth = baseTotal * (0.012 + random.nextDouble() * 0.006);
|
|
|
- baseTotal += growth;
|
|
|
- monthTotalUserList.add((double) Math.round(baseTotal)); // 取整数
|
|
|
- }
|
|
|
-
|
|
|
- // 3. 生成月活跃用户数据(月累积用户的1.2%-1.4%)
|
|
|
- List<Double> monthActiveUserList = new ArrayList<>();
|
|
|
- for (double total : monthTotalUserList) {
|
|
|
- double activeRate = 0.012 + random.nextDouble() * 0.002; // 1.2% - 1.4%
|
|
|
- monthActiveUserList.add((double) Math.round(total * activeRate)); // 取整数
|
|
|
- }
|
|
|
-
|
|
|
- // 4. 生成月活跃用户率(月活跃/月累积,保留两位小数)
|
|
|
- List<Double> monthActiveRateList = new ArrayList<>();
|
|
|
- for (int i = 0; i < dataSize; i++) {
|
|
|
- double rate = (monthActiveUserList.get(i) / monthTotalUserList.get(i)) * 100;
|
|
|
- monthActiveRateList.add(Math.round(rate * 100) / 100.0); // 保留两位小数
|
|
|
+ // 2. 定义存储列表
|
|
|
+ List<BigDecimal> activeList = new ArrayList<>();
|
|
|
+ List<BigDecimal> userList = new ArrayList<>();
|
|
|
+ List<BigDecimal> monthRateList = new ArrayList<>();
|
|
|
+ // 3. 遍历时间轴
|
|
|
+ for (String date : dates) {
|
|
|
+ LocalDateTime endTime = getEndTime(date, reqDto.getTimeUnit());
|
|
|
+ // 4. 查询、计算累计用户数
|
|
|
+ List<MktStatUserAnalysis> userAnalyses = userAnalysisMapper.selectList(Wrappers.<MktStatUserAnalysis>lambdaQuery()
|
|
|
+ .lt(MktStatUserAnalysis::getStatDate, endTime)
|
|
|
+ .select(MktStatUserAnalysis::getNewUser)
|
|
|
+ );
|
|
|
+ BigDecimal totalUser = BigDecimal.valueOf(userAnalyses.stream()
|
|
|
+ .mapToInt(MktStatUserAnalysis::getNewUser)
|
|
|
+ .sum());
|
|
|
+ userList.add(totalUser);
|
|
|
+ // 5. 查询、计算本月活跃用户数
|
|
|
+ BigDecimal activeUser = BigDecimal.valueOf(calculateNewUserCount(date, "All", reqDto.getChannel(), reqDto.getTimeUnit(), "activeUser"));
|
|
|
+ activeList.add(activeUser);
|
|
|
+ // 6. 计算月活跃率
|
|
|
+ BigDecimal monthRate = totalUser.compareTo(BigDecimal.ZERO) != 0 && activeUser.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? activeUser.divide(totalUser, 4, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO;
|
|
|
+ monthRateList.add(monthRate);
|
|
|
}
|
|
|
+ // 7. 组装结果数据
|
|
|
+ ActiveUserComposeVO totalUser = new ActiveUserComposeVO();
|
|
|
+ totalUser.setName("月累积用户");
|
|
|
+ totalUser.setKey("monthTotalUser");
|
|
|
+ totalUser.setVersion("All");
|
|
|
+ totalUser.setData(userList);
|
|
|
|
|
|
- // 5. 组装items数据
|
|
|
- List<ActiveUserComposeVO> items = new ArrayList<>();
|
|
|
-
|
|
|
- // 月累积用户
|
|
|
- ActiveUserComposeVO totalUserItem = new ActiveUserComposeVO();
|
|
|
- totalUserItem.setName("月累积用户");
|
|
|
- totalUserItem.setData(monthTotalUserList);
|
|
|
- items.add(totalUserItem);
|
|
|
-
|
|
|
- // 月活跃用户
|
|
|
- ActiveUserComposeVO activeUserItem = new ActiveUserComposeVO();
|
|
|
- activeUserItem.setName("月活跃用户");
|
|
|
- activeUserItem.setData(monthActiveUserList);
|
|
|
- items.add(activeUserItem);
|
|
|
-
|
|
|
- // 月活跃用户率
|
|
|
- ActiveUserComposeVO rateItem = new ActiveUserComposeVO();
|
|
|
- rateItem.setName("月活跃用户率");
|
|
|
- rateItem.setData(monthActiveRateList);
|
|
|
- items.add(rateItem);
|
|
|
-
|
|
|
- result.setItems(items);
|
|
|
+ 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);
|
|
|
+ result.setItems(Arrays.asList(totalUser, activeUser, monthRate));
|
|
|
return result;
|
|
|
}
|
|
|
|
|
@@ -630,67 +607,156 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
*/
|
|
|
@Override
|
|
|
public Page<PageActiveDetailVO> pageActiveDetail(PageActiveDetailDTO reqDto) {
|
|
|
+ // 活跃构成:活跃用户中新增用户的占比比例
|
|
|
+ // 活跃粘度:DAU/过去7日活跃用户,DAU/过去30日活跃用户
|
|
|
+ // 过去7日活跃用户:过去7日(不含今日)的活跃用户数(去重)
|
|
|
+ // 过去30日(不含今日)的活跃用户数(去重)
|
|
|
+
|
|
|
+ // 1. 初始化分页对象并计算总条数
|
|
|
Page<PageActiveDetailVO> page = new Page<>(reqDto.getCurrent(), reqDto.getSize());
|
|
|
- List<PageActiveDetailVO> result = new ArrayList<>();
|
|
|
- String timeUnit = reqDto.getTimeUnit();
|
|
|
- LocalDate fromDate = reqDto.getFromDate();
|
|
|
- LocalDate toDate = reqDto.getToDate();
|
|
|
+ page.setTotal(calculateTotalCount(reqDto.getFromDate(), reqDto.getToDate(), reqDto.getTimeUnit()));
|
|
|
|
|
|
- // 根据时间单位生成对应模拟数据
|
|
|
- if ("day".equals(timeUnit)) {
|
|
|
- // 生成按天的模拟数据
|
|
|
- LocalDate currentDate = fromDate;
|
|
|
- while (!currentDate.isAfter(toDate) && result.size() < reqDto.getSize()) {
|
|
|
- PageActiveDetailVO vo = new PageActiveDetailVO();
|
|
|
- vo.setDate(currentDate.toString());
|
|
|
- vo.setActiveUser(1300 + new Random().nextInt(200));
|
|
|
- vo.setMauRate(3.5 + new Random().nextDouble() * 1.5);
|
|
|
- vo.setWauRate(15 + new Random().nextDouble() * 5);
|
|
|
- vo.setNewUserRate(96 + new Random().nextDouble() * 2);
|
|
|
- result.add(vo);
|
|
|
- currentDate = currentDate.plusDays(1);
|
|
|
+ // 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 = "All";
|
|
|
+ if (reqDto.getVersion() != null && !reqDto.getVersion().isEmpty()){
|
|
|
+ version = reqDto.getVersion().get(0);
|
|
|
+ }
|
|
|
+ List<PageActiveDetailVO> result = new ArrayList<>();
|
|
|
+ if ("day".equals(reqDto.getTimeUnit())){
|
|
|
+ // 时间单位为天
|
|
|
+ for (String date : dates) {
|
|
|
+ LocalDateTime startTime = getStartTime(date, reqDto.getTimeUnit());
|
|
|
+ LocalDateTime endTime = getEndTime(date, reqDto.getTimeUnit());
|
|
|
+ LocalDateTime sevenDaysAgo = startTime.minusDays(7);
|
|
|
+ LocalDateTime thirtyDaysAgo = startTime.minusDays(30);
|
|
|
+
|
|
|
+ // 计算本周活跃用户
|
|
|
+ BigDecimal activeUser = BigDecimal.valueOf(calculateNewUserCount(date, version, reqDto.getChannel(), reqDto.getTimeUnit(), "activeUser"));
|
|
|
+ // 计算本周新增用户
|
|
|
+ BigDecimal newUser = BigDecimal.valueOf(calculateNewUserCount(date, version, reqDto.getChannel(), reqDto.getTimeUnit(), "newUser"));
|
|
|
+
|
|
|
+ // 计算活跃构成(新增/活跃)
|
|
|
+ BigDecimal newUserRate = activeUser.compareTo(BigDecimal.ZERO) != 0 && newUser.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? newUser.divide(activeUser, 4, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO;
|
|
|
+
|
|
|
+ // 过去7日活跃用户
|
|
|
+ List<MktStatUserAnalysis> sevenDaysUser = userAnalysisMapper.selectList(Wrappers.<MktStatUserAnalysis>lambdaQuery()
|
|
|
+ .ge(MktStatUserAnalysis::getStatDate, sevenDaysAgo)
|
|
|
+ .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 sevenDaysActiveUser = BigDecimal.valueOf(sevenDaysUser.stream()
|
|
|
+ .mapToInt(MktStatUserAnalysis::getActiveUser)
|
|
|
+ .sum());
|
|
|
+ BigDecimal sevenDaysNewUser = BigDecimal.valueOf(sevenDaysUser.stream()
|
|
|
+ .mapToInt(MktStatUserAnalysis::getNewUser)
|
|
|
+ .sum());
|
|
|
+ BigDecimal wauRate = sevenDaysNewUser.compareTo(BigDecimal.ZERO) != 0 && sevenDaysActiveUser.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? sevenDaysNewUser.divide(sevenDaysActiveUser, 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;
|
|
|
+
|
|
|
+ PageActiveDetailVO detail = new PageActiveDetailVO();
|
|
|
+ detail.setDate(date);
|
|
|
+ detail.setActiveUser(activeUser.intValue());
|
|
|
+ detail.setNewUserRate(newUserRate);
|
|
|
+ detail.setWauRate(wauRate);
|
|
|
+ detail.setMauRate(mauRate);
|
|
|
+ result.add(detail);
|
|
|
}
|
|
|
- } else if ("week".equals(timeUnit)) {
|
|
|
- // 生成按周的模拟数据
|
|
|
- LocalDate currentDate = fromDate;
|
|
|
- while (!currentDate.isAfter(toDate) && result.size() < reqDto.getSize()) {
|
|
|
- LocalDate endOfWeek = currentDate.plusDays(6);
|
|
|
- if (endOfWeek.isAfter(toDate)) {
|
|
|
- endOfWeek = toDate;
|
|
|
- }
|
|
|
- PageActiveDetailVO vo = new PageActiveDetailVO();
|
|
|
- vo.setDate(String.format("%s~%s",
|
|
|
- currentDate.format(DateTimeFormatter.ofPattern("yyyy/MM/dd")),
|
|
|
- endOfWeek.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"))));
|
|
|
- vo.setActiveUser(7500 + new Random().nextInt(500));
|
|
|
- vo.setWeekActiveUserRate(0.25 + new Random().nextDouble() * 0.1);
|
|
|
- vo.setNewUserRate(98.5 + new Random().nextDouble() * 0.5);
|
|
|
- result.add(vo);
|
|
|
- currentDate = currentDate.plusWeeks(1);
|
|
|
+
|
|
|
+ }
|
|
|
+ else if ("week".equals(reqDto.getTimeUnit())){
|
|
|
+ // 时间单位为周
|
|
|
+ for (String date : dates) {
|
|
|
+ LocalDateTime endTime = getEndTime(date, reqDto.getTimeUnit());
|
|
|
+ List<MktStatUserAnalysis> userAnalyses = userAnalysisMapper.selectList(Wrappers.<MktStatUserAnalysis>lambdaQuery()
|
|
|
+ .lt(MktStatUserAnalysis::getStatDate, endTime)
|
|
|
+ .select(MktStatUserAnalysis::getNewUser)
|
|
|
+ );
|
|
|
+ BigDecimal totalUser = BigDecimal.valueOf(userAnalyses.stream()
|
|
|
+ .mapToInt(MktStatUserAnalysis::getNewUser)
|
|
|
+ .sum());
|
|
|
+ // 计算本周活跃用户
|
|
|
+ BigDecimal activeUser = BigDecimal.valueOf(calculateNewUserCount(date, version, reqDto.getChannel(), reqDto.getTimeUnit(), "activeUser"));
|
|
|
+ // 计算本周新增用户
|
|
|
+ BigDecimal newUser = BigDecimal.valueOf(calculateNewUserCount(date, version, reqDto.getChannel(), reqDto.getTimeUnit(), "newUser"));
|
|
|
+ // 计算活跃构成(新增/活跃)
|
|
|
+ BigDecimal newUserRate = activeUser.compareTo(BigDecimal.ZERO) != 0 && newUser.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? newUser.divide(activeUser, 4, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO;
|
|
|
+
|
|
|
+ BigDecimal weekActiveUserRate = activeUser.compareTo(BigDecimal.ZERO) != 0 && totalUser.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? activeUser.divide(totalUser, 4, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO;
|
|
|
+
|
|
|
+ PageActiveDetailVO detail = new PageActiveDetailVO();
|
|
|
+ detail.setActiveUser(activeUser.intValue());
|
|
|
+ detail.setNewUserRate(newUserRate);
|
|
|
+ detail.setWeekActiveUserRate(weekActiveUserRate);
|
|
|
+ result.add( detail);
|
|
|
}
|
|
|
- } else if ("month".equals(timeUnit)) {
|
|
|
- // 生成按月的模拟数据
|
|
|
- LocalDate currentDate = fromDate;
|
|
|
- while (!currentDate.isAfter(toDate) && result.size() < reqDto.getSize()) {
|
|
|
- LocalDate endOfMonth = currentDate.plusMonths(1).minusDays(1);
|
|
|
- if (endOfMonth.isAfter(toDate)) {
|
|
|
- endOfMonth = toDate;
|
|
|
- }
|
|
|
- PageActiveDetailVO vo = new PageActiveDetailVO();
|
|
|
- vo.setDate(String.format("%s~%s",
|
|
|
- currentDate.format(DateTimeFormatter.ofPattern("yyyy/MM/dd")),
|
|
|
- endOfMonth.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"))));
|
|
|
- vo.setActiveUser(30000 + new Random().nextInt(5000));
|
|
|
- vo.setNewUserRate(99.4 + new Random().nextDouble() * 0.2);
|
|
|
- vo.setMonthActiveUserRate(1.2 + new Random().nextDouble() * 0.2);
|
|
|
- result.add(vo);
|
|
|
- currentDate = currentDate.plusMonths(1);
|
|
|
+
|
|
|
+ }
|
|
|
+ else if ("month".equals(reqDto.getTimeUnit())){
|
|
|
+ //时间单位为月
|
|
|
+ for (String date : dates) {
|
|
|
+ LocalDateTime endTime = getEndTime(date, reqDto.getTimeUnit());
|
|
|
+ List<MktStatUserAnalysis> userAnalyses = userAnalysisMapper.selectList(Wrappers.<MktStatUserAnalysis>lambdaQuery()
|
|
|
+ .lt(MktStatUserAnalysis::getStatDate, endTime)
|
|
|
+ .select(MktStatUserAnalysis::getNewUser)
|
|
|
+ );
|
|
|
+ BigDecimal totalUser = BigDecimal.valueOf(userAnalyses.stream()
|
|
|
+ .mapToInt(MktStatUserAnalysis::getNewUser)
|
|
|
+ .sum());
|
|
|
+ // 计算本月活跃用户
|
|
|
+ BigDecimal activeUser = BigDecimal.valueOf(calculateNewUserCount(date, version, reqDto.getChannel(), reqDto.getTimeUnit(), "activeUser"));
|
|
|
+ // 计算本月新增用户
|
|
|
+ BigDecimal newUser = BigDecimal.valueOf(calculateNewUserCount(date, version, reqDto.getChannel(), reqDto.getTimeUnit(), "newUser"));
|
|
|
+ // 计算活跃构成(新增/活跃)
|
|
|
+ BigDecimal newUserRate = activeUser.compareTo(BigDecimal.ZERO) != 0 && newUser.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? newUser.divide(activeUser, 4, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO;
|
|
|
+
|
|
|
+ BigDecimal monthActiveUserRate = activeUser.compareTo(BigDecimal.ZERO) != 0 && totalUser.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? activeUser.divide(totalUser, 4, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO;
|
|
|
+
|
|
|
+ PageActiveDetailVO detail = new PageActiveDetailVO();
|
|
|
+ detail.setActiveUser(activeUser.intValue());
|
|
|
+ detail.setNewUserRate(newUserRate);
|
|
|
+ detail.setMonthActiveUserRate(monthActiveUserRate);
|
|
|
+ result.add( detail);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- page.setRecords(result);
|
|
|
- // 模拟总条数,实际场景应根据查询条件计算
|
|
|
- page.setTotal(result.size() > 0 ? 100 : 0);
|
|
|
+ page.setRecords( result);
|
|
|
return page;
|
|
|
}
|
|
|
|
|
@@ -722,7 +788,7 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
|
|
|
// 计算每个时间点的启动次数
|
|
|
List<Integer> counts = dates.stream()
|
|
|
- .map(date -> calculateNewUserCount(date, version, reqDto, "launch"))
|
|
|
+ .map(date -> calculateNewUserCount(date, version, reqDto.getChannel(), reqDto.getTimeUnit(), "launch"))
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
trend.setData(counts);
|
|
@@ -1115,10 +1181,10 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
/**
|
|
|
* 计算单个时间点的数量
|
|
|
*/
|
|
|
- private Integer calculateNewUserCount(String date, String version, UserAnalyseQueryBaseDTO reqDto, String field) {
|
|
|
+ private Integer calculateNewUserCount(String date, String version, List<String> channels, String timeUnit, String field) {
|
|
|
// 1. 获取时间范围(开始和结束时间)
|
|
|
- LocalDateTime startTime = getStartTime(date, reqDto.getTimeUnit());
|
|
|
- LocalDateTime endTime = getEndTime(date, reqDto.getTimeUnit());
|
|
|
+ LocalDateTime startTime = getStartTime(date, timeUnit);
|
|
|
+ LocalDateTime endTime = getEndTime(date, timeUnit);
|
|
|
if (startTime == null || endTime == null) {
|
|
|
return 0;
|
|
|
}
|
|
@@ -1140,7 +1206,6 @@ public class UserAnalyseServiceImpl implements UserAnalyseService {
|
|
|
}
|
|
|
|
|
|
// 添加渠道条件
|
|
|
- List<String> channels = reqDto.getChannel();
|
|
|
if (channels != null && !channels.isEmpty()) {
|
|
|
queryWrapper.in(MktStatUserAnalysis::getChannel, channels);
|
|
|
}
|