content: package com.sky.service.impl;
  
  import com.sky.dto.GoodsSalesDTO;
  import com.sky.entity.Orders;
  import com.sky.mapper.OrderMapper;
  import com.sky.mapper.UserMapper;
  import com.sky.service.ReportService;
  import com.sky.service.WorkspaceService;
  import com.sky.vo.*;
  
  import org.apache.commons.lang.StringUtils;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Service;
  
  
  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;
  import java.util.stream.Collectors;
  
  @Service
  public class ReportServiceImpl implements ReportService {
  
      @Autowired
      private OrderMapper orderMapper;
  
      @Autowired
      private UserMapper userMapper;
  
      @Autowired
      private WorkspaceService workspaceService;
  
      /**
       * 营业额统计
       * 
       * @param begin
       * @param end
       * @return
       */
      @Override
      public TurnoverReportVO getTurnoverReport(LocalDate begin, LocalDate end) {
  
          List<LocalDate> dates = new ArrayList<>();
          dates.add(begin);
          while (begin.equals(end)) {
              begin = begin.plusDays(1);
              dates.add(begin);
          }
  
          List<Double> turnoverList = new ArrayList<>();
          for (LocalDate date : dates) {
              LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
              LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
              Map<String, Object> map = new HashMap<>();
              map.put("status", Orders.COMPLETED);
              map.put("begin", beginTime);
              map.put("end", endTime);
              Double turnover = orderMapper.sumByMap(map);
              turnover = turnover == null ? 0.0 : turnover;
              turnoverList.add(turnover);
          }
  
          return TurnoverReportVO.builder()
                  .dateList(StringUtils.join(dates, ","))
                  .turnoverList(StringUtils.join(turnoverList, ","))
                  .build();
      }
  
      /**
       * 根据时间区间统计用户数量
       * 
       * @param begin
       * @param end
       * @return
       */
      @Override
      public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {
          List<LocalDate> dateList = new ArrayList<>();
          dateList.add(begin);
  
          while (!begin.equals(end)) {
              begin = begin.plusDays(1);
              dateList.add(begin);
          }
          List<Integer> newUserList = new ArrayList<>(); // 新增用户数
          List<Integer> totalUserList = new ArrayList<>(); // 总用户数
  
          for (LocalDate date : dateList) {
              LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
              LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
              // 新增用户数量 select count(id) from user where create_time > ? and create_time < ?
              Integer newUser = getUserCount(beginTime, endTime);
              // 总用户数量 select count(id) from user where create_time < ?
              Integer totalUser = getUserCount(null, endTime);
  
              newUserList.add(newUser);
              totalUserList.add(totalUser);
          }
  
          return UserReportVO.builder()
                  .dateList(StringUtils.join(dateList, ","))
                  .newUserList(StringUtils.join(newUserList, ","))
                  .totalUserList(StringUtils.join(totalUserList, ","))
                  .build();
      }
  
      /**
       * 根据时间区间统计订单数量
       * 
       * @param begin
       * @param end
       * @return
       */
      public OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end) {
          List<LocalDate> dateList = new ArrayList<>();
          dateList.add(begin);
  
          while (!begin.equals(end)) {
              begin = begin.plusDays(1);
              dateList.add(begin);
          }
          // 每天订单总数集合
          List<Integer> orderCountList = new ArrayList<>();
          // 每天有效订单数集合
          List<Integer> validOrderCountList = new ArrayList<>();
          for (LocalDate date : dateList) {
              LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
              LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
              // 查询每天的总订单数 select count(id) from orders where order_time > ? and order_time <
              // ?
              Integer orderCount = getOrderCount(beginTime, endTime, null);
  
              // 查询每天的有效订单数 select count(id) from orders where order_time > ? and order_time <
              // ? and status = ?
              Integer validOrderCount = getOrderCount(beginTime, endTime, Orders.COMPLETED);
  
              orderCountList.add(orderCount);
              validOrderCountList.add(validOrderCount);
          }
  
          // 时间区间内的总订单数
          Integer totalOrderCount = orderCountList.stream().reduce((a, b) -> a + b).get();
          // 时间区间内的总有效订单数
          Integer validOrderCount = validOrderCountList.stream().reduce((a, b) -> a + b).get();
          // 订单完成率
          Double orderCompletionRate = 0.0;
          if (totalOrderCount != 0) {
              orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount;
          }
          return OrderReportVO.builder()
                  .dateList(StringUtils.join(dateList, ","))
                  .orderCountList(StringUtils.join(orderCountList, ","))
                  .validOrderCountList(StringUtils.join(validOrderCountList, ","))
                  .totalOrderCount(totalOrderCount)
                  .validOrderCount(validOrderCount)
                  .orderCompletionRate(orderCompletionRate)
                  .build();
  
      }
  
      /**
       * 查询指定时间区间内的销量排名top10
       * 
       * @param begin
       * @param end
       * @return
       */
      public SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end) {
          LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
          LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
          List<GoodsSalesDTO> goodsSalesDTOList = orderMapper.getSalesTop10(beginTime, endTime);
  
          String nameList = StringUtils
                  .join(goodsSalesDTOList.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList()), ",");
          String numberList = StringUtils
                  .join(goodsSalesDTOList.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList()), ",");
  
          return SalesTop10ReportVO.builder()
                  .nameList(nameList)
                  .numberList(numberList)
                  .build();
      }
  
      /**
       * 根据时间区间统计用户数量
       * 
       * @param beginTime
       * @param endTime
       * @return
       */
      private Integer getUserCount(LocalDateTime beginTime, LocalDateTime endTime) {
          Map<String, Object> map = new HashMap<>();
          map.put("begin", beginTime);
          map.put("end", endTime);
          return userMapper.countByMap(map);
      }
  
      /**
       * 根据时间区间统计指定状态的订单数量
       * 
       * @param beginTime
       * @param endTime
       * @param status
       * @return
       */
      private Integer getOrderCount(LocalDateTime beginTime, LocalDateTime endTime, Integer status) {
          Map<String, Object> map = new HashMap<>();
          map.put("status", status);
          map.put("begin", beginTime);
          map.put("end", endTime);
          return orderMapper.countByMap(map);
      }
  
  
  }
  