package com.tcm.training.admin.statistics.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.tcm.training.admin.live.entity.HealthCourse;
|
import com.tcm.training.admin.live.mapper.HealthCourseMapper;
|
import com.tcm.training.admin.member.entity.AppUser;
|
import com.tcm.training.admin.member.mapper.UserMapper;
|
import com.tcm.training.admin.points.entity.PointsExchangeOrder;
|
import com.tcm.training.admin.points.mapper.PointsExchangeOrderMapper;
|
import com.tcm.training.admin.statistics.mapper.RevenueStatisticsMapper;
|
import com.tcm.training.admin.statistics.mapper.UserStatisticsMapper;
|
import com.tcm.training.admin.statistics.row.RevenueStatisticsDailyRow;
|
import com.tcm.training.admin.statistics.row.UserStatisticsRegisterTrendRow;
|
import com.tcm.training.admin.statistics.vo.HomeDashboardOverviewVO;
|
import com.tcm.training.admin.statistics.vo.HomeDashboardRevenueTrendItemVO;
|
import com.tcm.training.admin.statistics.vo.HomeDashboardUserTrendItemVO;
|
import com.tcm.training.admin.statistics.vo.HomeDashboardVO;
|
import com.tcm.training.admin.trade.service.PaymentFlowAppService;
|
import org.springframework.stereotype.Service;
|
|
import java.math.BigDecimal;
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.time.LocalTime;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
@Service
|
public class HomeDashboardAppService {
|
|
private static final int HOME_RECENT_DAYS = 7;
|
|
private final UserMapper userMapper;
|
private final HealthCourseMapper healthCourseMapper;
|
private final PointsExchangeOrderMapper pointsExchangeOrderMapper;
|
private final UserStatisticsMapper userStatisticsMapper;
|
private final RevenueStatisticsMapper revenueStatisticsMapper;
|
private final PaymentFlowAppService paymentFlowAppService;
|
|
public HomeDashboardAppService(UserMapper userMapper,
|
HealthCourseMapper healthCourseMapper,
|
PointsExchangeOrderMapper pointsExchangeOrderMapper,
|
UserStatisticsMapper userStatisticsMapper,
|
RevenueStatisticsMapper revenueStatisticsMapper,
|
PaymentFlowAppService paymentFlowAppService) {
|
this.userMapper = userMapper;
|
this.healthCourseMapper = healthCourseMapper;
|
this.pointsExchangeOrderMapper = pointsExchangeOrderMapper;
|
this.userStatisticsMapper = userStatisticsMapper;
|
this.revenueStatisticsMapper = revenueStatisticsMapper;
|
this.paymentFlowAppService = paymentFlowAppService;
|
}
|
|
public HomeDashboardVO dashboard() {
|
LocalDate endDate = LocalDate.now();
|
LocalDate startDate = endDate.minusDays(HOME_RECENT_DAYS - 1L);
|
LocalDateTime startTime = startDate.atStartOfDay();
|
LocalDateTime endTime = LocalDateTime.of(endDate, LocalTime.MAX);
|
|
paymentFlowAppService.syncFlows();
|
|
HomeDashboardVO result = new HomeDashboardVO();
|
result.setOverview(buildOverview());
|
result.setUserRegisterTrend(buildUserRegisterTrend(
|
userStatisticsMapper.selectRegisterTrend(null, startTime, endTime),
|
startDate,
|
endDate
|
));
|
result.setRevenueTrend(buildRevenueTrend(
|
revenueStatisticsMapper.selectDailyStatistics(null, startTime, endTime),
|
startDate,
|
endDate
|
));
|
result.setPendingPointsExchangeShipmentCount(countPendingPointsExchangeShipment());
|
return result;
|
}
|
|
private HomeDashboardOverviewVO buildOverview() {
|
HomeDashboardOverviewVO overview = new HomeDashboardOverviewVO();
|
overview.setRegisteredUserCount(userMapper.selectCount(new LambdaQueryWrapper<AppUser>()
|
.eq(AppUser::getDeleted, 0)));
|
overview.setRegisteredDoctorCount(userMapper.selectCount(new LambdaQueryWrapper<AppUser>()
|
.eq(AppUser::getDeleted, 0)
|
.eq(AppUser::getType, 1)));
|
overview.setMemberUserCount(userMapper.selectCount(new LambdaQueryWrapper<AppUser>()
|
.eq(AppUser::getDeleted, 0)
|
.isNotNull(AppUser::getMemberExpireAt)
|
.gt(AppUser::getMemberExpireAt, LocalDateTime.now())));
|
overview.setHealthCourseCount(healthCourseMapper.selectCount(new LambdaQueryWrapper<HealthCourse>()
|
.eq(HealthCourse::getDeleted, 0)));
|
return overview;
|
}
|
|
private List<HomeDashboardUserTrendItemVO> buildUserRegisterTrend(List<UserStatisticsRegisterTrendRow> rows,
|
LocalDate startDate,
|
LocalDate endDate) {
|
Map<LocalDate, UserStatisticsRegisterTrendRow> rowMap = new HashMap<LocalDate, UserStatisticsRegisterTrendRow>();
|
for (UserStatisticsRegisterTrendRow row : rows) {
|
rowMap.put(row.getStatDate(), row);
|
}
|
|
List<HomeDashboardUserTrendItemVO> result = new ArrayList<HomeDashboardUserTrendItemVO>();
|
LocalDate cursor = startDate;
|
while (!cursor.isAfter(endDate)) {
|
UserStatisticsRegisterTrendRow row = rowMap.get(cursor);
|
HomeDashboardUserTrendItemVO item = new HomeDashboardUserTrendItemVO();
|
item.setDate(cursor.toString());
|
item.setRegisteredUserCount(nvl(row == null ? null : row.getRegisteredUserCount()));
|
result.add(item);
|
cursor = cursor.plusDays(1);
|
}
|
return result;
|
}
|
|
private List<HomeDashboardRevenueTrendItemVO> buildRevenueTrend(List<RevenueStatisticsDailyRow> rows,
|
LocalDate startDate,
|
LocalDate endDate) {
|
Map<LocalDate, RevenueStatisticsDailyRow> rowMap = new HashMap<LocalDate, RevenueStatisticsDailyRow>();
|
for (RevenueStatisticsDailyRow row : rows) {
|
rowMap.put(row.getStatDate(), row);
|
}
|
|
List<HomeDashboardRevenueTrendItemVO> result = new ArrayList<HomeDashboardRevenueTrendItemVO>();
|
LocalDate cursor = startDate;
|
while (!cursor.isAfter(endDate)) {
|
RevenueStatisticsDailyRow row = rowMap.get(cursor);
|
HomeDashboardRevenueTrendItemVO item = new HomeDashboardRevenueTrendItemVO();
|
item.setDate(cursor.toString());
|
item.setHealthIncome(nvl(row == null ? null : row.getHealthIncome()));
|
item.setMemberIncome(nvl(row == null ? null : row.getMemberIncome()));
|
result.add(item);
|
cursor = cursor.plusDays(1);
|
}
|
return result;
|
}
|
|
private Long countPendingPointsExchangeShipment() {
|
return pointsExchangeOrderMapper.selectCount(new LambdaQueryWrapper<PointsExchangeOrder>()
|
.eq(PointsExchangeOrder::getDeleted, 0)
|
.eq(PointsExchangeOrder::getStatus, 0));
|
}
|
|
private Long nvl(Long value) {
|
return value == null ? 0L : value;
|
}
|
|
private BigDecimal nvl(BigDecimal value) {
|
return value == null ? BigDecimal.ZERO : value;
|
}
|
}
|