From fc8b51f40e71aa09bb49f407c1e9f68ac94ceb58 Mon Sep 17 00:00:00 2001
From: mitao <2763622819@qq.com>
Date: 星期一, 29 七月 2024 18:51:32 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/MgtBusinessDataService.java |  277 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 268 insertions(+), 9 deletions(-)

diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/MgtBusinessDataService.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/MgtBusinessDataService.java
index db8ee35..90d2b31 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/MgtBusinessDataService.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/MgtBusinessDataService.java
@@ -1,44 +1,166 @@
 package com.ruoyi.order.service.impl;
 
+import com.ruoyi.common.core.enums.AuctionOrderTypeEnum;
+import com.ruoyi.common.core.enums.OrderFromEnum;
+import com.ruoyi.common.core.enums.OrderTypeEnum;
 import com.ruoyi.common.core.enums.TimeTypeEnum;
 import com.ruoyi.common.core.exception.ServiceException;
 import com.ruoyi.common.core.utils.DateUtils;
+import com.ruoyi.common.core.utils.page.CollUtils;
 import com.ruoyi.order.controller.management.dto.MgtOrderStaticsQuery;
+import com.ruoyi.order.controller.management.vo.MgtAmountChartVO;
+import com.ruoyi.order.controller.management.vo.MgtCountChartVO;
+import com.ruoyi.order.controller.management.vo.MgtOrderStaticsChartVO;
 import com.ruoyi.order.controller.management.vo.MgtOrderStaticsVO;
 import com.ruoyi.order.service.IOrderService;
+import com.ruoyi.system.api.domain.Order;
+import java.math.BigDecimal;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.jetbrains.annotations.NotNull;
 import org.springframework.stereotype.Service;
 
 /**
  * @author mitao
  * @date 2024/6/19
  */
+@Slf4j
 @Service
 @RequiredArgsConstructor
 public class MgtBusinessDataService {
 
     private final IOrderService orderService;
 
+    /**
+     * 获取业务数据统计
+     *
+     * @param query 订单统计查询对象
+     * @return MgtOrderStaticsVO
+     */
     public MgtOrderStaticsVO getOverview(MgtOrderStaticsQuery query) {
-        LocalDateTime now = LocalDateTime.now();
-        LocalDateTime startTime = null;
-        LocalDateTime endTime = null;
-        getTimeByTimeType(query, startTime, endTime, now);
-        return null;
+
+        List<LocalDateTime> timeByTimeType = getTimeByTimeType(query);
+        LocalDateTime startTime = timeByTimeType.get(0);
+        LocalDateTime endTime = timeByTimeType.get(1);
+        List<Order> orderList = orderService.getStaticsOrderList(startTime, endTime);
+        if (orderList.isEmpty()) {
+            throw new ServiceException("暂无数据");
+        }
+        MgtOrderStaticsVO mgtOrderStaticsVO = new MgtOrderStaticsVO();
+        /* ***************************************商城订单统计*************************************** */
+        // 商城订单统计-订单总数
+        long mallOrderTotalCount = orderList.stream()
+                .filter(order -> !order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS))
+                .count();
+        // 商城订单统计-订单总数
+        long mallOrderCount = orderList.stream()
+                .filter(order -> order.getOrderFrom().equals(OrderFromEnum.COMMODITY_ORDER))
+                .count();
+        // 商城订单统计-商城订单
+        long seckillOrderCount = orderList.stream()
+                .filter(order -> order.getOrderFrom().equals(OrderFromEnum.SNAP_ORDERS))
+                .count();
+        // 商城订单统计-团购订单
+        long groupPurchaseOrderCount = orderList.stream()
+                .filter(order -> order.getOrderFrom().equals(OrderFromEnum.GROUP_PURCHASE_ORDERS))
+                .count();
+        // 商城订单统计-订单总金额
+        BigDecimal mallOrderTotalAmount = orderList.stream()
+                .filter(order -> !order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS))
+                .map(Order::getTotalAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
+        // 商城订单统计 - 商城总金额
+        BigDecimal mallTotalAmount = orderList.stream()
+                .filter(order -> order.getOrderFrom().equals(OrderFromEnum.COMMODITY_ORDER))
+                .map(Order::getTotalAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
+        // 商城订单统计-秒杀总金额
+        BigDecimal seckillTotalAmount = orderList.stream()
+                .filter(order -> order.getOrderFrom().equals(OrderFromEnum.SNAP_ORDERS))
+                .map(Order::getTotalAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
+
+        // 商城订单统计-团购总金额
+        BigDecimal groupPurchaseTotalAmount = orderList.stream()
+                .filter(order -> order.getOrderFrom().equals(OrderFromEnum.GROUP_PURCHASE_ORDERS))
+                .map(Order::getTotalAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
+
+        mgtOrderStaticsVO.setMallOrderTotalCount(mallOrderTotalCount);
+        mgtOrderStaticsVO.setMallOrderCount(mallOrderCount);
+        mgtOrderStaticsVO.setSeckillOrderCount(seckillOrderCount);
+        mgtOrderStaticsVO.setGroupPurchaseOrderCount(groupPurchaseOrderCount);
+
+        mgtOrderStaticsVO.setMallOrderTotalAmount(mallOrderTotalAmount);
+        mgtOrderStaticsVO.setMallTotalAmount(mallTotalAmount);
+        mgtOrderStaticsVO.setSeckillTotalAmount(seckillTotalAmount);
+        mgtOrderStaticsVO.setGroupPurchaseTotalAmount(groupPurchaseTotalAmount);
+
+        /* ***************************************拍卖订单统计*************************************** */
+        // 拍卖订单统计-订单总数
+        long auctionOrderTotalCount = orderList.stream()
+                .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS))
+                .count();
+        // 拍卖订单统计-拍卖商品订单
+        long auctionGoodsOrderCount = orderList.stream()
+                .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS)
+                        && order.getAuctionOrderType().equals(AuctionOrderTypeEnum.REGULAR_ITEMS))
+                .count();
+        // 拍卖订单统计-拍卖场订单
+        long auctionSalesroomOrderCount = orderList.stream()
+                .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS)
+                        && order.getAuctionOrderType().equals(AuctionOrderTypeEnum.AUCTION_ITEMS))
+                .count();
+        // 拍卖订单统计-订单总金额
+        BigDecimal auctionOrderTotalAmount = orderList.stream()
+                .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS))
+                .map(Order::getTotalAmount)
+                .reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
+        // 拍卖订单统计-拍卖商品总金额
+        BigDecimal auctionGoodsTotalAmount = orderList.stream()
+                .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS)
+                        && order.getAuctionOrderType().equals(AuctionOrderTypeEnum.REGULAR_ITEMS)
+                )
+                .map(Order::getTotalAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
+        // 拍卖订单统计-拍卖场总金额
+        BigDecimal auctionSalesroomTotalAmount = orderList.stream()
+                .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS)
+                        && order.getAuctionOrderType().equals(AuctionOrderTypeEnum.AUCTION_ITEMS))
+                .map(Order::getTotalAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
+
+        mgtOrderStaticsVO.setAuctionOrderTotalCount(auctionOrderTotalCount);
+        mgtOrderStaticsVO.setAuctionGoodsOrderCount(auctionGoodsOrderCount);
+        mgtOrderStaticsVO.setAuctionSalesroomOrderCount(auctionSalesroomOrderCount);
+
+        mgtOrderStaticsVO.setAuctionOrderTotalAmount(auctionOrderTotalAmount);
+        mgtOrderStaticsVO.setAuctionGoodsTotalAmount(auctionGoodsTotalAmount);
+        mgtOrderStaticsVO.setAuctionSalesroomTotalAmount(auctionSalesroomTotalAmount);
+        return mgtOrderStaticsVO;
     }
 
-    private static void getTimeByTimeType(MgtOrderStaticsQuery query, LocalDateTime startTime,
-            LocalDateTime endTime, LocalDateTime now) {
+    private List<LocalDateTime> getTimeByTimeType(MgtOrderStaticsQuery query) {
+        LocalDateTime startTime;
+        LocalDateTime endTime;
+        List<LocalDateTime> range = new ArrayList<>();
+        LocalDateTime now = LocalDateTime.now();
         if (Objects.equals(TimeTypeEnum.TODAY.getCode(), query.getTimeType())) {
             startTime = DateUtils.getDayStart(now);
             endTime = DateUtils.getDayEnd(now);
         } else if (Objects.equals(TimeTypeEnum.PAST_SEVEN_DAYS.getCode(), query.getTimeType())) {
-            startTime = DateUtils.getDayStart(now.minusDays(7));
+            startTime = DateUtils.getDayStart(now.minusDays(6)); // 过去七天 为过去六天加今天
             endTime = DateUtils.getDayEnd(now);
         } else if (Objects.equals(TimeTypeEnum.PAST_THIRTY_DAYS.getCode(), query.getTimeType())) {
-            startTime = DateUtils.getDayStart(now.minusDays(30));
+            startTime = DateUtils.getDayStart(now.minusDays(29)); // 过去30天 为过去29天加今天
             endTime = DateUtils.getDayEnd(now);
         } else if (Objects.equals(TimeTypeEnum.CUSTOM.getCode(), query.getTimeType())) {
             if (Objects.isNull(query.getStartTime()) || Objects.isNull(query.getEndTime())) {
@@ -50,5 +172,142 @@
             startTime = DateUtils.getDayStart(now);
             endTime = DateUtils.getDayEnd(now);
         }
+        range.add(startTime);
+        range.add(endTime);
+        return range;
+    }
+
+    /**
+     * 获取图表数据
+     *
+     * @return MgtOrderStaticsChartVO
+     */
+    public MgtOrderStaticsChartVO getChart() {
+        LocalDateTime now = LocalDateTime.now();
+        LocalDateTime startTime = DateUtils.getDayStart(now.minusDays(29));
+        LocalDateTime endTime = DateUtils.getDayEnd(now);
+        List<LocalDate> datesBetween = getDatesBetween(startTime.toLocalDate(),
+                endTime.toLocalDate());
+        // 根据开始时间和结束时间,获取这个范围的每一天的日期
+        List<Order> orderList = orderService.getStaticsOrderList(startTime, endTime);
+        ExecutorService executorService = Executors.newFixedThreadPool(4);
+        // 商城订单总数
+        CompletableFuture<List<MgtCountChartVO>> mallOrderCountFuture = CompletableFuture.supplyAsync(
+                () -> getMgtCountChartVOS(datesBetween, orderList, OrderTypeEnum.MALL_ODER),
+                executorService);
+        // 商城订单总金额
+        CompletableFuture<List<MgtAmountChartVO>> mallOrderTotalAmountFuture = CompletableFuture.supplyAsync(
+                () -> getMgtAmountChartVOS(datesBetween, orderList, OrderTypeEnum.MALL_ODER),
+                executorService);
+        // 拍卖订单总数
+        CompletableFuture<List<MgtCountChartVO>> auctionOrderCountFuture = CompletableFuture.supplyAsync(
+                () -> getMgtCountChartVOS(datesBetween, orderList, OrderTypeEnum.AUCTION_ORDER),
+                executorService);
+        // 拍卖订单总金额
+        CompletableFuture<List<MgtAmountChartVO>> auctionOrderTotalAmountFuture = CompletableFuture.supplyAsync(
+                () -> getMgtAmountChartVOS(datesBetween, orderList, OrderTypeEnum.AUCTION_ORDER),
+                executorService);
+        // 使用 join 方法阻塞当前线程,直到所有任务完成
+        CompletableFuture.allOf(mallOrderCountFuture,
+                        mallOrderTotalAmountFuture, auctionOrderCountFuture, auctionOrderTotalAmountFuture)
+                .join();
+        MgtOrderStaticsChartVO mgtOrderStaticsChartVO = new MgtOrderStaticsChartVO();
+        try {
+            // 设置结果
+            mgtOrderStaticsChartVO.setMallOrderCountList(mallOrderCountFuture.get());
+            mgtOrderStaticsChartVO.setMallOrderTotalAmountList(mallOrderTotalAmountFuture.get());
+            mgtOrderStaticsChartVO.setAuctionOrderCountList(auctionOrderCountFuture.get());
+            mgtOrderStaticsChartVO.setAuctionOrderTotalAmountList(
+                    auctionOrderTotalAmountFuture.get());
+        } catch (InterruptedException | ExecutionException e) {
+            throw new RuntimeException(e);
+        } finally {
+            executorService.shutdown(); // 确保关闭线程池
+        }
+        return mgtOrderStaticsChartVO;
+    }
+
+    @NotNull
+    private static List<MgtAmountChartVO> getMgtAmountChartVOS(List<LocalDate> datesBetween,
+            List<Order> orderList, OrderTypeEnum type) {
+        Map<String, BigDecimal> orderTotalAmountMap;
+        if (type.equals(OrderTypeEnum.MALL_ODER)) {
+            orderTotalAmountMap = orderList.stream()
+                    .filter(order -> !order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS))
+                    .collect(Collectors.groupingBy(order -> order.getOrderTime().toLocalDate()
+                                    .format(DateTimeFormatter.ofPattern("MM-dd")),
+                            Collectors.reducing(BigDecimal.ZERO, Order::getTotalAmount,
+                                    BigDecimal::add)));
+        } else if (type.equals(OrderTypeEnum.AUCTION_ORDER)) {
+            orderTotalAmountMap = orderList.stream()
+                    .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS))
+                    .collect(Collectors.groupingBy(order -> order.getOrderTime().toLocalDate()
+                                    .format(DateTimeFormatter.ofPattern("MM-dd")),
+                            Collectors.reducing(BigDecimal.ZERO, Order::getTotalAmount,
+                                    BigDecimal::add)));
+        } else {
+            orderTotalAmountMap = null;
+        }
+        if (orderTotalAmountMap != null) {
+            return datesBetween.stream().map(date -> {
+                MgtAmountChartVO mgtAmountChartVO = new MgtAmountChartVO();
+                mgtAmountChartVO.setDate(date.format(DateTimeFormatter.ofPattern("MM-dd")));
+                BigDecimal orderTotalAmount = orderTotalAmountMap.get(
+                        date.format(DateTimeFormatter.ofPattern("MM-dd")));
+                mgtAmountChartVO.setValue(
+                        orderTotalAmount == null ? BigDecimal.ZERO : orderTotalAmount);
+                return mgtAmountChartVO;
+            }).collect(Collectors.toList());
+        } else {
+            return CollUtils.emptyList();
+        }
+    }
+
+    @NotNull
+    private static List<MgtCountChartVO> getMgtCountChartVOS(List<LocalDate> datesBetween,
+            List<Order> orderList, OrderTypeEnum type) {
+        Map<String, Long> orderCountMap;
+        if (type.equals(OrderTypeEnum.MALL_ODER)) {
+            orderCountMap = orderList.stream()
+                    .filter(order -> !order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS))
+                    .collect(Collectors.groupingBy(order -> order.getOrderTime().toLocalDate()
+                                    .format(DateTimeFormatter.ofPattern("MM-dd")),
+                            Collectors.counting()));
+        } else if (type.equals(OrderTypeEnum.AUCTION_ORDER)) {
+            orderCountMap = orderList.stream()
+                    .filter(order -> order.getOrderFrom().equals(OrderFromEnum.AUCTION_ORDERS))
+                    .collect(Collectors.groupingBy(order -> order.getOrderTime().toLocalDate()
+                                    .format(DateTimeFormatter.ofPattern("MM-dd")),
+                            Collectors.counting()));
+        } else {
+            orderCountMap = null;
+        }
+        if (orderCountMap != null) {
+            return datesBetween.stream().map(date -> {
+                MgtCountChartVO mgtCountChartVO = new MgtCountChartVO();
+                mgtCountChartVO.setDate(date.format(DateTimeFormatter.ofPattern("MM-dd")));
+                Long orderCount = orderCountMap.get(
+                        date.format(DateTimeFormatter.ofPattern("MM-dd")));
+                mgtCountChartVO.setValue(orderCount == null ? 0L : orderCount);
+                return mgtCountChartVO;
+            }).collect(Collectors.toList());
+        } else {
+            return CollUtils.emptyList();
+        }
+    }
+
+    public List<LocalDate> getDatesBetween(LocalDate startDate, LocalDate endDate) {
+        // 检查开始日期是否晚于结束日期
+        if (startDate.isAfter(endDate)) {
+            throw new IllegalArgumentException("开始日期必须早于结束日期");
+        }
+
+        // 使用ChronoUnit.DAYS.between计算日期差,并生成日期范围的流
+        long numOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate);
+
+        // 使用Stream.iterate生成日期序列,再用limit限制天数,最后collect收集结果
+        return Stream.iterate(startDate, date -> date.plusDays(1))
+                .limit(numOfDaysBetween + 1) // 加1是因为包含结束日期
+                .collect(Collectors.toList());
     }
 }

--
Gitblit v1.7.1