diff --git a/sky-server/src/main/java/com/sky/controller/admin/ReportController.java b/sky-server/src/main/java/com/sky/controller/admin/ReportController.java new file mode 100644 index 0000000..f5a79e1 --- /dev/null +++ b/sky-server/src/main/java/com/sky/controller/admin/ReportController.java @@ -0,0 +1,90 @@ +package com.sky.controller.admin; + +import com.sky.result.Result; +import com.sky.service.ReportService; +import com.sky.vo.OrderReportVO; +import com.sky.vo.SalesTop10ReportVO; +import com.sky.vo.TurnoverReportVO; +import com.sky.vo.UserReportVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDate; + +@RestController +@RequestMapping("/admin/report") +@Api(tags = "数据统计相关接口") +@Slf4j +public class ReportController { + + @Autowired + private ReportService reportService; + + /** + * 营业额统计 + * + * @param begin + * @param end + * @return + */ + @GetMapping("/turnoverStatistics") + @ApiOperation("营业额统计") + public Result turnoverStatistics( + @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin, + @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) { + log.info("营业额数据统计:{}-{}", begin, end); + return Result.success(reportService.getTurnoverStatistics(begin, end)); + } + + /** + * 用户统计 + * + * @param begin + * @param end + * @return + */ + @GetMapping("/userStatistics") + @ApiOperation("用户统计") + public Result userStatistics( + @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin, + @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) { + log.info("用户数据统计:{}-{}", begin, end); + return Result.success(reportService.getUserStatistics(begin, end)); + } + + /** + * 订单统计 + * @param begin + * @param end + * @return + */ + @GetMapping("/ordersStatistics") + @ApiOperation("订单统计") + public Result orderStatistics( + @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin, + @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) { + log.info("订单数据统计:{}-{}", begin, end); + return Result.success(reportService.getOrderStatistics(begin, end)); + } + + /** + * 销量排名统计 + * @param begin + * @param end + * @return + */ + @GetMapping("/top10") + @ApiOperation("销量排名统计") + public Result top10( + @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin, + @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){ + log.info("销量排名数据统计:{}-{}", begin, end); + return Result.success(reportService.getSalesTop10(begin,end)); + } +} diff --git a/sky-server/src/main/java/com/sky/mapper/OrderMapper.java b/sky-server/src/main/java/com/sky/mapper/OrderMapper.java index d507584..323884a 100644 --- a/sky-server/src/main/java/com/sky/mapper/OrderMapper.java +++ b/sky-server/src/main/java/com/sky/mapper/OrderMapper.java @@ -1,13 +1,16 @@ package com.sky.mapper; import com.github.pagehelper.Page; +import com.sky.dto.GoodsSalesDTO; import com.sky.dto.OrdersPageQueryDTO; import com.sky.entity.Orders; +import io.swagger.models.auth.In; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import java.time.LocalDateTime; import java.util.List; +import java.util.Map; @Mapper public interface OrderMapper { @@ -60,4 +63,25 @@ public interface OrderMapper { */ @Select("select * from orders where status = #{status} and order_time < #{orderTime}") List getByStatusAndOrdertimeLT(Integer status, LocalDateTime orderTime); + + /** + * 根据动态条件查询营业额 + * @param map + * @return + */ + Double sumByMap(Map map); + + /** + * 根据动态条件查询订单数量 + * @param map + * @return + */ + Integer countByMap(Map map); + + /** + * 查询商品销量排名 + * @param begin + * @param end + */ + List getSalesTop10(LocalDateTime begin, LocalDateTime end); } diff --git a/sky-server/src/main/java/com/sky/mapper/UserMapper.java b/sky-server/src/main/java/com/sky/mapper/UserMapper.java index 1faebaa..9f92629 100644 --- a/sky-server/src/main/java/com/sky/mapper/UserMapper.java +++ b/sky-server/src/main/java/com/sky/mapper/UserMapper.java @@ -4,6 +4,8 @@ import com.sky.entity.User; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; +import java.util.Map; + @Mapper public interface UserMapper { @@ -28,4 +30,11 @@ public interface UserMapper { */ @Select("select * from user where id = #{userId}") User getById(Long userId); + + /** + * 根据动态条件查询用户数量 + * @param map + * @return + */ + Integer countByMap(Map map); } diff --git a/sky-server/src/main/java/com/sky/service/ReportService.java b/sky-server/src/main/java/com/sky/service/ReportService.java new file mode 100644 index 0000000..44152b7 --- /dev/null +++ b/sky-server/src/main/java/com/sky/service/ReportService.java @@ -0,0 +1,43 @@ +package com.sky.service; + +import com.sky.vo.OrderReportVO; +import com.sky.vo.SalesTop10ReportVO; +import com.sky.vo.TurnoverReportVO; +import com.sky.vo.UserReportVO; + +import java.time.LocalDate; + +public interface ReportService { + + /** + * 获取营业额统计数据 + * @param begin + * @param end + * @return + */ + TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end); + + /** + * 获取用户统计数据 + * @param begin + * @param end + * @return + */ + UserReportVO getUserStatistics(LocalDate begin, LocalDate end); + + /** + * 获取订单统计数据 + * @param begin + * @param end + * @return + */ + OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end); + + /** + * 获取销售排行榜数据 + * @param begin + * @param end + * @return + */ + SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end); +} diff --git a/sky-server/src/main/java/com/sky/service/impl/ReportServiceImpl.java b/sky-server/src/main/java/com/sky/service/impl/ReportServiceImpl.java new file mode 100644 index 0000000..65e94f1 --- /dev/null +++ b/sky-server/src/main/java/com/sky/service/impl/ReportServiceImpl.java @@ -0,0 +1,219 @@ +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.UserService; +import com.sky.vo.OrderReportVO; +import com.sky.vo.SalesTop10ReportVO; +import com.sky.vo.TurnoverReportVO; +import com.sky.vo.UserReportVO; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.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 +@Slf4j +public class ReportServiceImpl implements ReportService { + + @Autowired + private OrderMapper orderMapper; + @Autowired + private UserService userService; + @Autowired + private UserMapper userMapper; + + /** + * 获取营业额统计数据 + * + * @param begin + * @param end + * @return + */ + public TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end) { + //计算日期范围集合 + List dateList = new ArrayList<>(); + dateList.add(begin); + while (!begin.equals(end)) { + //计算指定日期的下一天 + begin = begin.plusDays(1); + dateList.add(begin); + } + String dateListStr = StringUtils.join(dateList, ","); + + //查询营业额数据 + List turnoverList = new ArrayList<>(); + for (LocalDate date : dateList) { + //查询指定日期的营业额数据:状态已完成的订单的总金额 + LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN); + LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX); + + Map 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); + } + String turnoverListStr = StringUtils.join(turnoverList, ","); + + //组装数据对象 + return TurnoverReportVO + .builder() + .dateList(dateListStr) + .turnoverList(turnoverListStr) + .build(); + } + + /** + * 获取用户统计数据 + * + * @param begin + * @param end + * @return + */ + public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) { + //计算日期范围集合 + List dateList = new ArrayList<>(); + dateList.add(begin); + while (!begin.equals(end)) { + //计算指定日期的下一天 + begin = begin.plusDays(1); + dateList.add(begin); + } + String dateListStr = StringUtils.join(dateList, ","); + + List newUserList = new ArrayList<>(); + List totalUserList = new ArrayList<>(); + + for (LocalDate date : dateList) { + //查询指定日期的营业额数据:状态已完成的订单的总金额 + LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN); + LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX); + + Map map = new HashMap(); + map.put("end", endTime); + + //总用户数量 + Integer totalUser = userMapper.countByMap(map); + + map.put("begin", beginTime); + Integer newUser = userMapper.countByMap(map); + + totalUserList.add(totalUser); + newUserList.add(newUser); + } + return UserReportVO + .builder() + .dateList(dateListStr) + .totalUserList(StringUtils.join(totalUserList, ",")) + .newUserList(StringUtils.join(newUserList, ",")) + .build(); + } + + /** + * 获取订单统计数据 + * + * @param begin + * @param end + * @return + */ + public OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end) { + //计算日期范围集合 + List dateList = new ArrayList<>(); + dateList.add(begin); + while (!begin.equals(end)) { + //计算指定日期的下一天 + begin = begin.plusDays(1); + dateList.add(begin); + } + + //每天订单总数集合 + List orderCountList = new ArrayList<>(); + //每天有效订单数集合 + List 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(Integer::sum).get(); + //时间区间内的总有效订单数 + Integer validOrderCount = validOrderCountList.stream().reduce(Integer::sum).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(); + } + + /** + * 获取销售排行榜数据 + * + * @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 goodsSalesDTOList = orderMapper.getSalesTop10(beginTime, endTime); + + List names = goodsSalesDTOList.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList()); + String nameList = StringUtils.join(names,","); + + List numbers = goodsSalesDTOList.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList()); + String numberList = StringUtils.join(numbers,","); + + return SalesTop10ReportVO.builder() + .nameList(nameList) + .numberList(numberList) + .build(); + } + + /** + * 根据时间区间统计指定状态的订单数量 + * + * @param beginTime + * @param endTime + * @param status + * @return + */ + private Integer getOrderCount(LocalDateTime beginTime, LocalDateTime endTime, Integer status) { + Map map = new HashMap(); + map.put("status", status); + map.put("begin", beginTime); + map.put("end", endTime); + return orderMapper.countByMap(map); + } +} diff --git a/sky-server/src/main/resources/mapper/OrderMapper.xml b/sky-server/src/main/resources/mapper/OrderMapper.xml index ddfaebd..1c4986f 100644 --- a/sky-server/src/main/resources/mapper/OrderMapper.xml +++ b/sky-server/src/main/resources/mapper/OrderMapper.xml @@ -67,4 +67,47 @@ order by order_time desc + + + + diff --git a/sky-server/src/main/resources/mapper/UserMapper.xml b/sky-server/src/main/resources/mapper/UserMapper.xml index d4cc4e5..72ed5db 100644 --- a/sky-server/src/main/resources/mapper/UserMapper.xml +++ b/sky-server/src/main/resources/mapper/UserMapper.xml @@ -8,4 +8,15 @@ insert into user (openid, name, phone, sex, id_number, avatar, create_time) values (#{openid}, #{name}, #{phone}, #{sex}, #{idNumber}, #{avatar}, #{createTime}) +