package com.kym.service.impl; import cn.dev33.satoken.stp.StpUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.kym.common.utils.CommUtil; import com.kym.entity.WashDevice; import com.kym.entity.WashOrder; import com.kym.entity.queryParams.StatQueryParam; import com.kym.entity.vo.DashboardVo; import com.kym.entity.vo.StationTrendVo; import com.kym.service.*; import com.kym.service.cache.KymCache; import org.springframework.stereotype.Service; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.temporal.TemporalAdjusters; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * 统计 */ @Service public class StatServiceImpl implements StatService { private final UserService userService; private final WashOrderService washOrderService; private final WashDeviceService washDeviceService; public StatServiceImpl(UserService userService, WashOrderService washOrderService, WashDeviceService washDeviceService) { this.userService = userService; this.washOrderService = washOrderService; this.washDeviceService = washDeviceService; } @Override public Map getTodayConsumption() { return washOrderService.sumAmountByDate(LocalDate.now()); } @Override public Map getMonthConsumption() { return washOrderService.sumMonthAmount(LocalDate.now()); } @Override public Integer getTotalConsumption() { return null; } @Override public Integer getTotalRegistrations() { return (int) userService.count(); } /** * 当月订单平均消费金额 * * @return */ @Override public Integer getAvgPrice() { // int totalAmountMap = washOrderService.sumMonthAmount(LocalDate.now()); // int totalOrdersMap = washOrderService.countMonthOrdersCount(LocalDate.now()); // // todo 按照站点 分组统计 // return totalOrders == 0 ? 0 : totalAmount / totalOrders; return null; } /** * 平均洗车时长 * * @return */ @Override public Integer getAvgDuration() { var startTime = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN); var endTime = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX); LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.ge(WashOrder::getStartTime, startTime); wrapper.gt(WashOrder::getStartTime, endTime); var list = washOrderService.list(wrapper); if (!list.isEmpty()) { var totalSeconds = list.stream().mapToInt(WashOrder::getTotalSeconds).sum(); return totalSeconds / list.size(); } return null; } /** * 当月用户平均洗车频率 * * @return */ @Override public Double getAvgFrequency() { var startTime = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN); var endTime = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX); LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.ge(WashOrder::getStartTime, startTime); wrapper.gt(WashOrder::getStartTime, endTime); var list = washOrderService.list(wrapper); // 洗车人数 var users = list.stream().distinct().map(WashOrder::getUserId).count(); return users == 0 ? 0 : (double) Math.round((double) list.size() / users * 100) / 100; } /** * 今日概要 * * @return */ @Override public DashboardVo dashboard(String stationId) { // 截止到现在今日的所有洗车订单 var todayOrders = washOrderService.lambdaQuery() .eq(WashOrder::getStationId, stationId) .ge(WashOrder::getStartTime, LocalDateTime.of(LocalDate.now(), LocalTime.MIN)) .list(); // 今日收入:V2结算方案从订单中计算 var todayIncome = todayOrders.stream().mapToInt(WashOrder::getAmountReceived).sum(); // 站点今日注册人数 var todayRegistrations = userService.countDailyRegister(LocalDate.now(), stationId); // 平均洗车消费单价(分) var avgOrderPrice = todayOrders.isEmpty() ? 0 : (int)todayIncome/todayOrders.size(); // 平均洗车时长(秒) var avgOrderDuration = todayOrders.isEmpty() ? 0 : (int)todayOrders.stream().mapToInt(WashOrder::getTotalSeconds).sum() / todayOrders.size(); // 月度数据 var monthOrders = washOrderService.lambdaQuery() .eq(WashOrder::getStationId, stationId) .ge(WashOrder::getStartTime, LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).atTime(LocalTime.MIN)) .le(WashOrder::getStartTime, LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).atTime(LocalTime.MAX)) .list(); var monthConsumptionAmount = monthOrders.stream().mapToInt(WashOrder::getAmount).sum(); var monthIncome = monthOrders.stream().mapToInt(WashOrder::getAmountReceived).sum(); var monthRegistrations = userService.countMonthRegister(LocalDate.now()); var monthOrdersMap = washOrderService.countMonthOrders(LocalDate.now()); // 累计数据 var allOrders = washOrderService.lambdaQuery() .eq(WashOrder::getStationId, stationId) .list(); var totalIncome = allOrders.stream().mapToInt(WashOrder::getAmountReceived).sum(); var totalConsumptionAmount = allOrders.stream().mapToInt(WashOrder::getAmount).sum(); var totalMembers = (int) userService.count(); DashboardVo dashboardVo = new DashboardVo(); dashboardVo.setTodayIncome(todayIncome); dashboardVo.setTodayConsumptionAmount(todayOrders.stream().mapToInt(WashOrder::getAmount).sum()); dashboardVo.setTodayWashOrders(todayOrders.size()); dashboardVo.setTodayRegisteredMembers(CommUtil.isEmptyOrNull(todayRegistrations) ? 0 : todayRegistrations.getOrDefault(stationId, 0)); dashboardVo.setMonthIncome(monthIncome); dashboardVo.setMonthConsumptionAmount(monthConsumptionAmount); dashboardVo.setMonthRegisteredMembers(monthRegistrations.getOrDefault(stationId, 0)); dashboardVo.setMonthWashOrders(monthOrdersMap.getOrDefault(stationId, 0)); dashboardVo.setTotalIncome(totalIncome); dashboardVo.setTotalConsumptionAmount(totalConsumptionAmount); dashboardVo.setTotalWashOrders(allOrders.size()); dashboardVo.setTotalRegisteredMembers(totalMembers); dashboardVo.setAvgOrderPrice(avgOrderPrice); dashboardVo.setAvgOrderDuration(avgOrderDuration); // 平均洗车频率(次) dashboardVo.setAvgWashFrequency(0.0); // todo return dashboardVo; } /** * 统计站点的设备状态情况 * * @param stationId * @return */ @Override public Map washDeviceStatus(String stationId) { return washDeviceService.lambdaQuery().eq(WashDevice::getStationId, stationId).list() .stream().collect((Collectors.groupingBy(WashDevice::getState, Collectors.counting()))); } @Override public List trend(StatQueryParam params) { // 判断数据权限 var adminStationIds = KymCache.INSTANCE.getAdminUserStationIds(StpUtil.getLoginIdAsLong()); if (CommUtil.isEmptyOrNull(params.getStationId()) && CommUtil.isNotEmptyAndNull(adminStationIds)) { params.setStationId(adminStationIds.get(0)); } if (CommUtil.isNotEmptyAndNull(params.getStationId()) && CommUtil.isNotEmptyAndNull(adminStationIds) && !adminStationIds.contains(params.getStationId())) { params.setStationId(adminStationIds.get(0)); } return washOrderService.stationTrend(params); } }