From d3385dcb4f7305e5632164e7c9b4defc3d0e58d5 Mon Sep 17 00:00:00 2001
From: owen <owen@evolsun.com>
Date: Mon, 16 Oct 2023 13:52:00 +0800
Subject: [PATCH] =?UTF-8?q?=E7=BB=9F=E8=AE=A1=EF=BC=9A=E4=BC=9A=E5=91=98?=
 =?UTF-8?q?=E5=88=86=E6=9E=90=E6=95=B0=E6=8D=AE=E6=8E=A5=E5=8F=A3=E9=87=8D?=
 =?UTF-8?q?=E6=9E=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../member/MemberStatisticsController.java    | 34 ++++++++++++++++--
 ...spVO.java => MemberAnalyseDataRespVO.java} |  4 +--
 .../admin/member/vo/MemberAnalyseRespVO.java  |  2 +-
 .../member/MemberStatisticsConvert.java       |  9 ++++-
 .../member/MemberStatisticsService.java       |  8 ++---
 .../member/MemberStatisticsServiceImpl.java   | 36 ++++++-------------
 6 files changed, 57 insertions(+), 36 deletions(-)
 rename yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/{MemberAnalyseComparisonRespVO.java => MemberAnalyseDataRespVO.java} (83%)

diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/MemberStatisticsController.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/MemberStatisticsController.java
index b78b207b5..211d340f5 100644
--- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/MemberStatisticsController.java
+++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/MemberStatisticsController.java
@@ -1,11 +1,16 @@
 package cn.iocoder.yudao.module.statistics.controller.admin.member;
 
 import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.NumberUtil;
 import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
+import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.module.statistics.controller.admin.common.vo.DataComparisonRespVO;
 import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.*;
+import cn.iocoder.yudao.module.statistics.convert.member.MemberStatisticsConvert;
+import cn.iocoder.yudao.module.statistics.service.infra.ApiAccessLogStatisticsService;
 import cn.iocoder.yudao.module.statistics.service.member.MemberStatisticsService;
+import cn.iocoder.yudao.module.statistics.service.trade.TradeOrderStatisticsService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.extern.slf4j.Slf4j;
@@ -16,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import java.time.LocalDateTime;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -30,6 +36,10 @@ public class MemberStatisticsController {
 
     @Resource
     private MemberStatisticsService memberStatisticsService;
+    @Resource
+    private TradeOrderStatisticsService tradeOrderStatisticsService;
+    @Resource
+    private ApiAccessLogStatisticsService apiAccessLogStatisticsService;
 
     // TODO 芋艿:已经 review
     @GetMapping("/summary")
@@ -44,8 +54,28 @@ public class MemberStatisticsController {
     @Operation(summary = "获得会员分析数据")
     @PreAuthorize("@ss.hasPermission('statistics:member:query')")
     public CommonResult<MemberAnalyseRespVO> getMemberAnalyse(MemberAnalyseReqVO reqVO) {
-        return success(memberStatisticsService.getMemberAnalyse(
-                ArrayUtil.get(reqVO.getTimes(), 0), ArrayUtil.get(reqVO.getTimes(), 1)));
+        // 1. 查询数据
+        LocalDateTime beginTime = ArrayUtil.get(reqVO.getTimes(), 0);
+        LocalDateTime endTime = ArrayUtil.get(reqVO.getTimes(), 1);
+        // 1.1 查询分析对照数据
+        DataComparisonRespVO<MemberAnalyseDataRespVO> comparisonData = memberStatisticsService.getMemberAnalyseComparisonData(beginTime, endTime);
+        // TODO @疯狂:这个可能有点特殊,要按照 create_time 来查询;不然它的漏斗就不统一;因为是访问数量 > 今日下单人 > 今日支付人;是一个统一的维度;
+        // 1.2 查询成交用户数量
+        Integer payUserCount = tradeOrderStatisticsService.getPayUserCount(beginTime, endTime);
+        // 1.3 计算客单价
+        int atv = 0;
+        if (payUserCount != null && payUserCount > 0) {
+            // TODO @疯狂:类似上面的 payUserCount
+            Integer payPrice = tradeOrderStatisticsService.getOrderPayPrice(beginTime, endTime);
+            atv = NumberUtil.div(payPrice, payUserCount).intValue();
+        }
+        // 1.4 查询访客数量
+        Integer visitUserCount = apiAccessLogStatisticsService.getIpCount(UserTypeEnum.MEMBER.getValue(), beginTime, endTime);
+        // 1.5 下单用户数量
+        Integer orderUserCount = tradeOrderStatisticsService.getOrderUserCount(beginTime, endTime);
+
+        // 2. 拼接返回
+        return success(MemberStatisticsConvert.INSTANCE.convert(visitUserCount, orderUserCount, payUserCount, atv, comparisonData));
     }
 
     // TODO 芋艿:已经 review
diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberAnalyseComparisonRespVO.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberAnalyseDataRespVO.java
similarity index 83%
rename from yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberAnalyseComparisonRespVO.java
rename to yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberAnalyseDataRespVO.java
index 58675f681..d2dd3e483 100644
--- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberAnalyseComparisonRespVO.java
+++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberAnalyseDataRespVO.java
@@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.statistics.controller.admin.member.vo;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
-@Schema(description = "管理后台 - 会员分析对照数据 Response VO")
+@Schema(description = "管理后台 - 会员分析数据 Response VO")
 @Data
-public class MemberAnalyseComparisonRespVO {
+public class MemberAnalyseDataRespVO {
 
     @Schema(description = "会员数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private Integer registerUserCount;
diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberAnalyseRespVO.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberAnalyseRespVO.java
index a235f53f8..e1c46547b 100644
--- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberAnalyseRespVO.java
+++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberAnalyseRespVO.java
@@ -21,6 +21,6 @@ public class MemberAnalyseRespVO {
     private Integer atv;
 
     @Schema(description = "对照数据", requiredMode = Schema.RequiredMode.REQUIRED)
-    private DataComparisonRespVO<MemberAnalyseComparisonRespVO> comparison;
+    private DataComparisonRespVO<MemberAnalyseDataRespVO> comparison;
 
 }
diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/convert/member/MemberStatisticsConvert.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/convert/member/MemberStatisticsConvert.java
index 794a66717..14a1bcad8 100644
--- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/convert/member/MemberStatisticsConvert.java
+++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/convert/member/MemberStatisticsConvert.java
@@ -4,6 +4,9 @@ import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ObjUtil;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.ip.core.Area;
+import cn.iocoder.yudao.module.statistics.controller.admin.common.vo.DataComparisonRespVO;
+import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberAnalyseDataRespVO;
+import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberAnalyseRespVO;
 import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberAreaStatisticsRespVO;
 import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberSummaryRespVO;
 import cn.iocoder.yudao.module.statistics.service.pay.bo.RechargeSummaryRespBO;
@@ -28,7 +31,8 @@ public interface MemberStatisticsConvert {
                                                          Map<Integer, Integer> userCountMap,
                                                          Map<Integer, MemberAreaStatisticsRespVO> orderMap) {
         return CollectionUtils.convertList(areaList, area -> {
-            MemberAreaStatisticsRespVO orderVo = Optional.ofNullable(orderMap.get(area.getId())).orElseGet(MemberAreaStatisticsRespVO::new);
+            MemberAreaStatisticsRespVO orderVo = Optional.ofNullable(orderMap.get(area.getId()))
+                    .orElseGet(MemberAreaStatisticsRespVO::new);
             return new MemberAreaStatisticsRespVO()
                     .setAreaId(area.getId()).setAreaName(area.getName())
                     .setUserCount(MapUtil.getInt(userCountMap, area.getId(), 0))
@@ -40,4 +44,7 @@ public interface MemberStatisticsConvert {
 
     MemberSummaryRespVO convert(RechargeSummaryRespBO rechargeSummary, Integer expensePrice, Integer userCount);
 
+    MemberAnalyseRespVO convert(Integer visitUserCount, Integer orderUserCount, Integer payUserCount, int atv,
+                                DataComparisonRespVO<MemberAnalyseDataRespVO> comparison);
+
 }
diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/member/MemberStatisticsService.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/member/MemberStatisticsService.java
index da9a61ac1..af875f456 100644
--- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/member/MemberStatisticsService.java
+++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/member/MemberStatisticsService.java
@@ -21,15 +21,15 @@ public interface MemberStatisticsService {
      */
     MemberSummaryRespVO getMemberSummary();
 
-    // TODO 芋艿:已经 review
     /**
-     * 获取用户分析数据
+     * 获取会员分析对照数据
      *
      * @param beginTime 起始时间
      * @param endTime   截止时间
-     * @return 用户分析数据
+     * @return 会员分析对照数据
      */
-    MemberAnalyseRespVO getMemberAnalyse(LocalDateTime beginTime, LocalDateTime endTime);
+    DataComparisonRespVO<MemberAnalyseDataRespVO> getMemberAnalyseComparisonData(LocalDateTime beginTime,
+                                                                                 LocalDateTime endTime);
 
     /**
      * 按照省份,获得会员统计列表
diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/member/MemberStatisticsServiceImpl.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/member/MemberStatisticsServiceImpl.java
index 981146e04..f06c98ae8 100644
--- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/member/MemberStatisticsServiceImpl.java
+++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/member/MemberStatisticsServiceImpl.java
@@ -1,7 +1,6 @@
 package cn.iocoder.yudao.module.statistics.service.member;
 
 import cn.hutool.core.date.LocalDateTimeUtil;
-import cn.hutool.core.util.NumberUtil;
 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.ip.core.Area;
 import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
@@ -79,37 +78,22 @@ public class MemberStatisticsServiceImpl implements MemberStatisticsService {
         return MemberStatisticsConvert.INSTANCE.convertList(areaList, userCountMap, orderMap);
     }
 
-    // TODO @疯狂:这个方法,要不拆成:1)controller 调用 getMemberAnalyseComparisonData;2)tradeOrderStatisticsService.getPayUserCount;3)tradeOrderStatisticsService.getOrderPayPrice;4)。。。
-    // TODO 就是说:分析交给 controller 去组合;
     @Override
-    public MemberAnalyseRespVO getMemberAnalyse(LocalDateTime beginTime, LocalDateTime endTime) {
+    public DataComparisonRespVO<MemberAnalyseDataRespVO> getMemberAnalyseComparisonData(LocalDateTime beginTime, LocalDateTime endTime) {
+        // 当前数据
+        MemberAnalyseDataRespVO vo = getMemberAnalyseData(beginTime, endTime);
         // 对照数据
-        MemberAnalyseComparisonRespVO vo = getMemberAnalyseComparisonData(beginTime, endTime);
-        // TODO @疯狂:如果时间段这么处理,会不会 beginTime 重叠了。因为是 <= 一个时间;如果数据库插入的是 ,xxxx-yy-zz 00:00:00 的话,它既满足 >= ? 也满足 <= ;(如果不好理解,微信聊)
-        LocalDateTime referenceBeginTime = beginTime.minus(Duration.between(beginTime, endTime));
-        MemberAnalyseComparisonRespVO reference = getMemberAnalyseComparisonData(referenceBeginTime, beginTime);
-
-        // 计算客单价
-        // TODO @疯狂:这个可能有点特殊,要按照 create_time 来查询;不然它的漏斗就不统一;因为是访问数量 > 今日下单人 > 今日支付人;是一个统一的维度;
-        Integer payUserCount = tradeOrderStatisticsService.getPayUserCount(beginTime, endTime);
-        int atv = 0;
-        if (payUserCount != null && payUserCount > 0) {
-            // TODO @疯狂:类似上面的 payUserCount
-            Integer payPrice = tradeOrderStatisticsService.getOrderPayPrice(beginTime, endTime);
-            atv = NumberUtil.div(payPrice, payUserCount).intValue();
-        }
-        return new MemberAnalyseRespVO()
-                .setVisitUserCount(apiAccessLogStatisticsService.getIpCount(UserTypeEnum.MEMBER.getValue(), beginTime, endTime))
-                .setOrderUserCount(tradeOrderStatisticsService.getOrderUserCount(beginTime, endTime))
-                .setPayUserCount(payUserCount)
-                .setAtv(atv)
-                .setComparison(new DataComparisonRespVO<>(vo, reference));
+        LocalDateTime referenceEndDate = beginTime.minusDays(1); // 减少1天,防止出现时间重叠
+        LocalDateTime referenceBeginDate = referenceEndDate.minus(Duration.between(beginTime, endTime));
+        MemberAnalyseDataRespVO reference = getMemberAnalyseData(
+                LocalDateTimeUtil.beginOfDay(referenceBeginDate), LocalDateTimeUtil.endOfDay(referenceEndDate));
+        return new DataComparisonRespVO<>(vo, reference);
     }
 
-    private MemberAnalyseComparisonRespVO getMemberAnalyseComparisonData(LocalDateTime beginTime, LocalDateTime endTime) {
+    private MemberAnalyseDataRespVO getMemberAnalyseData(LocalDateTime beginTime, LocalDateTime endTime) {
         Integer rechargeUserCount = Optional.ofNullable(payWalletStatisticsService.getUserRechargeSummary(beginTime, endTime))
                 .map(RechargeSummaryRespBO::getRechargeUserCount).orElse(0);
-        return new MemberAnalyseComparisonRespVO()
+        return new MemberAnalyseDataRespVO()
                 .setRegisterUserCount(memberStatisticsMapper.selectUserCount(beginTime, endTime))
                 .setVisitUserCount(apiAccessLogStatisticsService.getUserCount(UserTypeEnum.MEMBER.getValue(), beginTime, endTime))
                 .setRechargeUserCount(rechargeUserCount);