Commit 1ac2f2b5c2e906b7760abd7b2d07da129698ec70
1 parent
0eb86ca2
code review:会员统计
Showing
24 changed files
with
86 additions
and
41 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/TerminalEnum.java
| ... | ... | @@ -18,8 +18,7 @@ public enum TerminalEnum implements IntArrayValuable { |
| 18 | 18 | WECHAT_MINI_PROGRAM(10, "微信小程序"), |
| 19 | 19 | WECHAT_WAP(11, "微信公众号"), |
| 20 | 20 | H5(20, "H5 网页"), |
| 21 | - IOS(31, "苹果 App"), | |
| 22 | - ANDROID(32, "安卓 App"), | |
| 21 | + APP(31, "手机 App"), | |
| 23 | 22 | ; |
| 24 | 23 | |
| 25 | 24 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TerminalEnum::getTerminal).toArray(); | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java
| ... | ... | @@ -145,18 +145,15 @@ public class AreaUtils { |
| 145 | 145 | if (area == null) { |
| 146 | 146 | return null; |
| 147 | 147 | } |
| 148 | - | |
| 149 | - // 匹配到 | |
| 148 | + // 情况一:匹配到,返回它 | |
| 150 | 149 | if (type.getType().equals(area.getType())) { |
| 151 | 150 | return area.getId(); |
| 152 | 151 | } |
| 153 | - | |
| 154 | - // 找到根节点,返回空 | |
| 152 | + // 情况二:找到根节点,返回空 | |
| 155 | 153 | if (area.getParent() == null || area.getParent().getId() == null) { |
| 156 | 154 | return null; |
| 157 | 155 | } |
| 158 | - | |
| 159 | - // 继续向上查找 | |
| 156 | + // 其它:继续向上查找 | |
| 160 | 157 | id = area.getParent().getId(); |
| 161 | 158 | } |
| 162 | 159 | return null; | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/MemberStatisticsController.java
| ... | ... | @@ -30,13 +30,15 @@ public class MemberStatisticsController { |
| 30 | 30 | @Resource |
| 31 | 31 | private MemberStatisticsService memberStatisticsService; |
| 32 | 32 | |
| 33 | + // TODO 芋艿:已经 review | |
| 33 | 34 | @GetMapping("/summary") |
| 34 | - @Operation(summary = "获得会员统计") | |
| 35 | + @Operation(summary = "获得会员统计(实时统计)") | |
| 35 | 36 | @PreAuthorize("@ss.hasPermission('statistics:member:query')") |
| 36 | 37 | public CommonResult<MemberSummaryRespVO> getMemberSummary() { |
| 37 | 38 | return success(memberStatisticsService.getMemberSummary()); |
| 38 | 39 | } |
| 39 | 40 | |
| 41 | + // TODO 芋艿:已经 review | |
| 40 | 42 | @GetMapping("/analyse") |
| 41 | 43 | @Operation(summary = "获得会员分析数据") |
| 42 | 44 | @PreAuthorize("@ss.hasPermission('statistics:member:query')") |
| ... | ... | @@ -45,6 +47,7 @@ public class MemberStatisticsController { |
| 45 | 47 | ArrayUtil.get(reqVO.getTimes(), 0), ArrayUtil.get(reqVO.getTimes(), 1))); |
| 46 | 48 | } |
| 47 | 49 | |
| 50 | + // TODO 芋艿:已经 review | |
| 48 | 51 | @GetMapping("/get-area-statistics-list") |
| 49 | 52 | @Operation(summary = "按照省份,获得会员统计列表") |
| 50 | 53 | @PreAuthorize("@ss.hasPermission('statistics:member:query')") |
| ... | ... | @@ -52,6 +55,7 @@ public class MemberStatisticsController { |
| 52 | 55 | return success(memberStatisticsService.getMemberAreaStatisticsList()); |
| 53 | 56 | } |
| 54 | 57 | |
| 58 | + // TODO 芋艿:已经 review | |
| 55 | 59 | @GetMapping("/get-sex-statistics-list") |
| 56 | 60 | @Operation(summary = "按照性别,获得会员统计列表") |
| 57 | 61 | @PreAuthorize("@ss.hasPermission('statistics:member:query')") |
| ... | ... | @@ -64,6 +68,7 @@ public class MemberStatisticsController { |
| 64 | 68 | @PreAuthorize("@ss.hasPermission('statistics:member:query')") |
| 65 | 69 | public CommonResult<List<MemberTerminalStatisticsRespVO>> getMemberTerminalStatisticsList() { |
| 66 | 70 | // TODO 疯狂:这个可以晚点写,因为 user = = 上还没记录 terminal |
| 71 | + // TODO @疯狂:在 member_user 上,增加 registerTerminal 字段,基于它来统计哈; | |
| 67 | 72 | List<MemberTerminalStatisticsRespVO> list = convertList(TerminalEnum.values(), |
| 68 | 73 | t -> new MemberTerminalStatisticsRespVO() |
| 69 | 74 | .setTerminal(t.getTerminal()).setUserCount(t.getTerminal() * 100)); | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberAnalyseComparisonRespVO.java
| ... | ... | @@ -7,9 +7,11 @@ import lombok.Data; |
| 7 | 7 | @Data |
| 8 | 8 | public class MemberAnalyseComparisonRespVO { |
| 9 | 9 | |
| 10 | + // TODO @疯狂:这个字段,要不改成注册用户量;registerUserCount; | |
| 10 | 11 | @Schema(description = "会员数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 11 | 12 | private Integer userCount; |
| 12 | 13 | |
| 14 | + // TODO @疯狂:这个字段,名字改成 visitUserCount;有访问,就算活跃; | |
| 13 | 15 | @Schema(description = "活跃用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 14 | 16 | private Integer activeUserCount; |
| 15 | 17 | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberAnalyseRespVO.java
| ... | ... | @@ -8,6 +8,7 @@ import lombok.Data; |
| 8 | 8 | @Data |
| 9 | 9 | public class MemberAnalyseRespVO { |
| 10 | 10 | |
| 11 | + // TODO @疯狂:这个字段改成 visitUserCount,保持和 userCount 字段统一 | |
| 11 | 12 | @Schema(description = "访客数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 12 | 13 | private Integer visitorCount; |
| 13 | 14 | |
| ... | ... | @@ -17,7 +18,7 @@ public class MemberAnalyseRespVO { |
| 17 | 18 | @Schema(description = "成交用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 18 | 19 | private Integer payUserCount; |
| 19 | 20 | |
| 20 | - @Schema(description = "客单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | |
| 21 | + @Schema(description = "客单价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | |
| 21 | 22 | private Integer atv; |
| 22 | 23 | |
| 23 | 24 | @Schema(description = "对照数据", requiredMode = Schema.RequiredMode.REQUIRED) | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberAreaStatisticsRespVO.java
| ... | ... | @@ -15,10 +15,12 @@ public class MemberAreaStatisticsRespVO { |
| 15 | 15 | @Schema(description = "会员数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 16 | 16 | private Integer userCount; |
| 17 | 17 | |
| 18 | + // TODO @疯狂:要不 orderCreateUserCount 和 orderPayUserCount 貌似更统一一些; | |
| 18 | 19 | @Schema(description = "订单创建数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 19 | 20 | private Integer orderCreateCount; |
| 20 | 21 | @Schema(description = "订单支付数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "512") |
| 21 | 22 | private Integer orderPayCount; |
| 23 | + | |
| 22 | 24 | @Schema(description = "订单支付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "622") |
| 23 | 25 | private Integer orderPayPrice; |
| 24 | 26 | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberSexStatisticsRespVO.java
| ... | ... | @@ -10,6 +10,7 @@ public class MemberSexStatisticsRespVO { |
| 10 | 10 | @Schema(description = "性别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 11 | 11 | private Integer sex; |
| 12 | 12 | |
| 13 | + // TODO @疯狂:要不还是其它字段,我们也补全,这样方便使用的用户,做定制化;就保持和 MemberAreaStatisticsRespVO 一致; | |
| 13 | 14 | @Schema(description = "会员数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 14 | 15 | private Integer userCount; |
| 15 | 16 | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberSummaryRespVO.java
| ... | ... | @@ -13,10 +13,11 @@ public class MemberSummaryRespVO { |
| 13 | 13 | @Schema(description = "充值会员数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "221") |
| 14 | 14 | private Integer rechargeUserCount; |
| 15 | 15 | |
| 16 | - @Schema(description = "充值金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | |
| 16 | + @Schema(description = "充值金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | |
| 17 | 17 | private Integer rechargePrice; |
| 18 | 18 | |
| 19 | - @Schema(description = "支出金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | |
| 20 | - private Integer expensePrice; | |
| 19 | + // TODO @疯狂:要不干脆这个字段改成:orderPayPrice?? | |
| 20 | + @Schema(description = "支出金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | |
| 21 | + private Integer expensePrice; // 只计算 mall 交易订单的支付金额,不考虑退款 | |
| 21 | 22 | |
| 22 | 23 | } | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/member/vo/MemberTerminalStatisticsRespVO.java
| ... | ... | @@ -10,6 +10,7 @@ public class MemberTerminalStatisticsRespVO { |
| 10 | 10 | @Schema(description = "终端", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 11 | 11 | private Integer terminal; |
| 12 | 12 | |
| 13 | + // TODO @疯狂:要不 orderCreateUserCount 和 orderPayUserCount 貌似更统一一些; | |
| 13 | 14 | @Schema(description = "会员数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 14 | 15 | private Integer userCount; |
| 15 | 16 | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/vo/TradeStatisticsComparisonRespVO.java
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/mysql/infra/ApiAccessLogStatisticsMapper.java
| ... | ... | @@ -14,9 +14,11 @@ import java.time.LocalDateTime; |
| 14 | 14 | @Mapper |
| 15 | 15 | public interface ApiAccessLogStatisticsMapper extends BaseMapperX<Object> { |
| 16 | 16 | |
| 17 | + // TODO @疯狂:是不是 selectIpCount | |
| 17 | 18 | Integer selectCountByIp(@Param("beginTime") LocalDateTime beginTime, |
| 18 | 19 | @Param("endTime") LocalDateTime endTime); |
| 19 | 20 | |
| 21 | + // TODO @疯狂:是不是 selectUserCount | |
| 20 | 22 | Integer selectCountByUserId(@Param("beginTime") LocalDateTime beginTime, |
| 21 | 23 | @Param("endTime") LocalDateTime endTime); |
| 22 | 24 | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/mysql/member/MemberStatisticsMapper.java
| ... | ... | @@ -17,10 +17,13 @@ import java.util.List; |
| 17 | 17 | @Mapper |
| 18 | 18 | public interface MemberStatisticsMapper extends BaseMapperX<Object> { |
| 19 | 19 | |
| 20 | + // TODO @芋艿:已经 review | |
| 21 | + // TODO @疯狂:要不还是搞下 bo?虽然可能冗余了点~~ | |
| 20 | 22 | List<MemberAreaStatisticsRespVO> selectSummaryListByAreaId(); |
| 21 | 23 | |
| 22 | 24 | List<MemberSexStatisticsRespVO> selectSummaryListBySex(); |
| 23 | 25 | |
| 26 | + // TODO @芋艿:已经 review | |
| 24 | 27 | Integer selectUserCount(@Param("beginTime") LocalDateTime beginTime, |
| 25 | 28 | @Param("endTime") LocalDateTime endTime); |
| 26 | 29 | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/mysql/pay/PayWalletStatisticsMapper.java
| ... | ... | @@ -29,6 +29,7 @@ public interface PayWalletStatisticsMapper extends BaseMapperX<TradeStatisticsDO |
| 29 | 29 | @Param("endTime") LocalDateTime endTime, |
| 30 | 30 | @Param("bizType") Integer bizType); |
| 31 | 31 | |
| 32 | + // TODO 芋艿:已经 review; | |
| 32 | 33 | RechargeSummaryRespBO selectRechargeSummaryGroupByWalletId(@Param("beginTime") LocalDateTime beginTime, |
| 33 | 34 | @Param("endTime") LocalDateTime endTime, |
| 34 | 35 | @Param("payStatus") Boolean payStatus); | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/mysql/trade/TradeOrderStatisticsMapper.java
| ... | ... | @@ -17,6 +17,7 @@ import java.util.List; |
| 17 | 17 | @Mapper |
| 18 | 18 | public interface TradeOrderStatisticsMapper extends BaseMapperX<TradeStatisticsDO> { |
| 19 | 19 | |
| 20 | + // TODO 芋艿:已经 review | |
| 20 | 21 | List<MemberAreaStatisticsRespVO> selectSummaryListByAreaId(); |
| 21 | 22 | |
| 22 | 23 | Integer selectCountByCreateTimeBetween(@Param("beginTime") LocalDateTime beginTime, |
| ... | ... | @@ -25,12 +26,15 @@ public interface TradeOrderStatisticsMapper extends BaseMapperX<TradeStatisticsD |
| 25 | 26 | Integer selectCountByPayTimeBetween(@Param("beginTime") LocalDateTime beginTime, |
| 26 | 27 | @Param("endTime") LocalDateTime endTime); |
| 27 | 28 | |
| 29 | + // TODO 芋艿:已经 review | |
| 28 | 30 | Integer selectSummaryPriceByPayTimeBetween(@Param("beginTime") LocalDateTime beginTime, |
| 29 | 31 | @Param("endTime") LocalDateTime endTime); |
| 30 | 32 | |
| 33 | + // TODO 芋艿:已经 review | |
| 31 | 34 | Integer selectUserCountByCreateTimeBetween(@Param("beginTime") LocalDateTime beginTime, |
| 32 | 35 | @Param("endTime") LocalDateTime endTime); |
| 33 | 36 | |
| 37 | + // TODO 芋艿:已经 review | |
| 34 | 38 | Integer selectUserCountByPayTimeBetween(@Param("beginTime") LocalDateTime beginTime, |
| 35 | 39 | @Param("endTime") LocalDateTime endTime); |
| 36 | 40 | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/infra/ApiAccessLogStatisticsService.java
| ... | ... | @@ -9,6 +9,8 @@ import java.time.LocalDateTime; |
| 9 | 9 | */ |
| 10 | 10 | public interface ApiAccessLogStatisticsService { |
| 11 | 11 | |
| 12 | + // TODO @疯狂:需要传递 userType;因为访问日志,可能涉及多种用户类型; | |
| 13 | + // TODO @疯狂:方法名,要不改成 getUserCount;原因:让它更业务无关 | |
| 12 | 14 | /** |
| 13 | 15 | * 获取活跃用户数量 |
| 14 | 16 | * |
| ... | ... | @@ -18,6 +20,8 @@ public interface ApiAccessLogStatisticsService { |
| 18 | 20 | */ |
| 19 | 21 | Integer getActiveUserCount(LocalDateTime beginTime, LocalDateTime endTime); |
| 20 | 22 | |
| 23 | + // TODO @疯狂:需要传递 userType;因为访问日志,可能涉及多种用户类型; | |
| 24 | + // TODO @疯狂:方法名,要不改成 getIpCount;原因:让它更业务无关 | |
| 21 | 25 | /** |
| 22 | 26 | * 获取访问用户数量 |
| 23 | 27 | * | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/infra/ApiAccessLogStatisticsServiceImpl.java
| ... | ... | @@ -28,4 +28,5 @@ public class ApiAccessLogStatisticsServiceImpl implements ApiAccessLogStatistics |
| 28 | 28 | public Integer getVisitorUserCount(LocalDateTime beginTime, LocalDateTime endTime) { |
| 29 | 29 | return apiAccessLogStatisticsMapper.selectCountByIp(beginTime, endTime); |
| 30 | 30 | } |
| 31 | + | |
| 31 | 32 | } | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/member/MemberStatisticsService.java
| ... | ... | @@ -15,13 +15,24 @@ import java.util.List; |
| 15 | 15 | */ |
| 16 | 16 | public interface MemberStatisticsService { |
| 17 | 17 | |
| 18 | + // TODO 芋艿:已经 review | |
| 18 | 19 | /** |
| 19 | - * 获取会员统计 | |
| 20 | + * 获取会员统计(实时统计) | |
| 20 | 21 | * |
| 21 | 22 | * @return 会员统计 |
| 22 | 23 | */ |
| 23 | 24 | MemberSummaryRespVO getMemberSummary(); |
| 24 | 25 | |
| 26 | + // TODO 芋艿:已经 review | |
| 27 | + /** | |
| 28 | + * 获取用户分析数据 | |
| 29 | + * | |
| 30 | + * @param beginTime 起始时间 | |
| 31 | + * @param endTime 截止时间 | |
| 32 | + * @return 用户分析数据 | |
| 33 | + */ | |
| 34 | + MemberAnalyseRespVO getMemberAnalyse(LocalDateTime beginTime, LocalDateTime endTime); | |
| 35 | + | |
| 25 | 36 | /** |
| 26 | 37 | * 按照省份,获得会员统计列表 |
| 27 | 38 | * |
| ... | ... | @@ -36,13 +47,4 @@ public interface MemberStatisticsService { |
| 36 | 47 | */ |
| 37 | 48 | List<MemberSexStatisticsRespVO> getMemberSexStatisticsList(); |
| 38 | 49 | |
| 39 | - /** | |
| 40 | - * 获取用户分析数据 | |
| 41 | - * | |
| 42 | - * @param beginTime 起始时间 | |
| 43 | - * @param endTime 截止时间 | |
| 44 | - * @return 用户分析数据 | |
| 45 | - */ | |
| 46 | - MemberAnalyseRespVO getMemberAnalyse(LocalDateTime beginTime, LocalDateTime endTime); | |
| 47 | - | |
| 48 | 50 | } | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/member/MemberStatisticsServiceImpl.java
| ... | ... | @@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum; |
| 5 | 5 | import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; |
| 6 | 6 | import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.*; |
| 7 | 7 | import cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeStatisticsComparisonRespVO; |
| 8 | -import cn.iocoder.yudao.module.statistics.convert.member.MemberStatisticsConvert; | |
| 9 | 8 | import cn.iocoder.yudao.module.statistics.dal.mysql.member.MemberStatisticsMapper; |
| 10 | 9 | import cn.iocoder.yudao.module.statistics.service.infra.ApiAccessLogStatisticsService; |
| 11 | 10 | import cn.iocoder.yudao.module.statistics.service.pay.PayWalletStatisticsService; |
| ... | ... | @@ -14,6 +13,7 @@ import cn.iocoder.yudao.module.statistics.service.trade.TradeOrderStatisticsServ |
| 14 | 13 | import cn.iocoder.yudao.module.statistics.service.trade.TradeStatisticsService; |
| 15 | 14 | import org.springframework.stereotype.Service; |
| 16 | 15 | import org.springframework.validation.annotation.Validated; |
| 16 | +import cn.iocoder.yudao.module.statistics.convert.member.MemberStatisticsConvert; | |
| 17 | 17 | |
| 18 | 18 | import javax.annotation.Resource; |
| 19 | 19 | import java.time.Duration; |
| ... | ... | @@ -46,8 +46,19 @@ public class MemberStatisticsServiceImpl implements MemberStatisticsService { |
| 46 | 46 | private ApiAccessLogStatisticsService apiAccessLogStatisticsService; |
| 47 | 47 | |
| 48 | 48 | @Override |
| 49 | + public MemberSummaryRespVO getMemberSummary() { | |
| 50 | + RechargeSummaryRespBO rechargeSummary = payWalletStatisticsService.getUserRechargeSummary(null, null); | |
| 51 | + // TODO @疯狂:1)这里是实时统计,不好走走 TradeStatistics 表;2)因为这个放在商城下,所以只考虑订单数据,即按照 trade_order 的 pay_price 并且已支付来计算; | |
| 52 | + Integer expensePrice = tradeStatisticsService.getExpensePrice(null, null); | |
| 53 | + Integer userCount = memberStatisticsMapper.selectUserCount(null, null); | |
| 54 | + return MemberStatisticsConvert.INSTANCE.convert(rechargeSummary, expensePrice, userCount); | |
| 55 | + } | |
| 56 | + | |
| 57 | + @Override | |
| 49 | 58 | public List<MemberAreaStatisticsRespVO> getMemberAreaStatisticsList() { |
| 50 | 59 | // 统计用户 |
| 60 | + // TODO @疯狂:要处理下,未知省份;就是没填写省份的情况; | |
| 61 | + // TODO @疯狂:可能得把每个省的用户,都查询出来,然后去 order 那边 in;因为要按照这些人为基础来计算;;用户规模量大可能不太好,但是暂时就先这样搞吧 = = | |
| 51 | 62 | Map<Integer, Integer> userCountMap = convertMap(memberStatisticsMapper.selectSummaryListByAreaId(), |
| 52 | 63 | vo -> AreaUtils.getParentIdByType(vo.getAreaId(), AreaTypeEnum.PROVINCE), |
| 53 | 64 | MemberAreaStatisticsRespVO::getUserCount, Integer::sum); |
| ... | ... | @@ -63,22 +74,22 @@ public class MemberStatisticsServiceImpl implements MemberStatisticsService { |
| 63 | 74 | return MemberStatisticsConvert.INSTANCE.convertList(AreaUtils.getByType(AreaTypeEnum.PROVINCE, area -> area), userCountMap, orderMap); |
| 64 | 75 | } |
| 65 | 76 | |
| 66 | - @Override | |
| 67 | - public List<MemberSexStatisticsRespVO> getMemberSexStatisticsList() { | |
| 68 | - return memberStatisticsMapper.selectSummaryListBySex(); | |
| 69 | - } | |
| 70 | - | |
| 77 | + // TODO @疯狂:这个方法,要不拆成:1)controller 调用 getMemberAnalyseComparisonData;2)tradeOrderStatisticsService.getPayUserCount;3)tradeOrderStatisticsService.getOrderPayPrice;4)。。。 | |
| 78 | + // TODO 就是说:分析交给 controller 去组合; | |
| 71 | 79 | @Override |
| 72 | 80 | public MemberAnalyseRespVO getMemberAnalyse(LocalDateTime beginTime, LocalDateTime endTime) { |
| 73 | 81 | // 对照数据 |
| 74 | 82 | MemberAnalyseComparisonRespVO vo = getMemberAnalyseComparisonData(beginTime, endTime); |
| 83 | + // TODO @疯狂:如果时间段这么处理,会不会 beginTime 重叠了。因为是 <= 一个时间;如果数据库插入的是 ,xxxx-yy-zz 00:00:00 的话,它既满足 >= ? 也满足 <= ;(如果不好理解,微信聊) | |
| 75 | 84 | LocalDateTime referenceBeginTime = beginTime.minus(Duration.between(beginTime, endTime)); |
| 76 | 85 | MemberAnalyseComparisonRespVO reference = getMemberAnalyseComparisonData(referenceBeginTime, beginTime); |
| 77 | 86 | |
| 78 | - Integer payUserCount = tradeOrderStatisticsService.getPayUserCount(beginTime, endTime); | |
| 79 | 87 | // 计算客单价 |
| 88 | + // TODO @疯狂:这个可能有点特殊,要按照 create_time 来查询;不然它的漏斗就不统一;因为是访问数量 > 今日下单人 > 今日支付人;是一个统一的维度; | |
| 89 | + Integer payUserCount = tradeOrderStatisticsService.getPayUserCount(beginTime, endTime); | |
| 80 | 90 | int atv = 0; |
| 81 | 91 | if (payUserCount != null && payUserCount > 0) { |
| 92 | + // TODO @疯狂:类似上面的 payUserCount | |
| 82 | 93 | Integer payPrice = tradeOrderStatisticsService.getOrderPayPrice(beginTime, endTime); |
| 83 | 94 | atv = NumberUtil.div(payPrice, payUserCount).intValue(); |
| 84 | 95 | } |
| ... | ... | @@ -90,15 +101,6 @@ public class MemberStatisticsServiceImpl implements MemberStatisticsService { |
| 90 | 101 | .setComparison(new TradeStatisticsComparisonRespVO<>(vo, reference)); |
| 91 | 102 | } |
| 92 | 103 | |
| 93 | - @Override | |
| 94 | - public MemberSummaryRespVO getMemberSummary() { | |
| 95 | - RechargeSummaryRespBO rechargeSummary = payWalletStatisticsService.getUserRechargeSummary(null, null); | |
| 96 | - Integer expensePrice = tradeStatisticsService.getExpensePrice(null, null); | |
| 97 | - Integer userCount = memberStatisticsMapper.selectUserCount(null, null); | |
| 98 | - | |
| 99 | - return MemberStatisticsConvert.INSTANCE.convert(rechargeSummary, expensePrice, userCount); | |
| 100 | - } | |
| 101 | - | |
| 102 | 104 | private MemberAnalyseComparisonRespVO getMemberAnalyseComparisonData(LocalDateTime beginTime, LocalDateTime endTime) { |
| 103 | 105 | Integer rechargeUserCount = Optional.ofNullable(payWalletStatisticsService.getUserRechargeSummary(beginTime, endTime)) |
| 104 | 106 | .map(RechargeSummaryRespBO::getRechargeUserCount).orElse(0); |
| ... | ... | @@ -108,4 +110,10 @@ public class MemberStatisticsServiceImpl implements MemberStatisticsService { |
| 108 | 110 | .setRechargeUserCount(rechargeUserCount); |
| 109 | 111 | } |
| 110 | 112 | |
| 113 | + @Override | |
| 114 | + public List<MemberSexStatisticsRespVO> getMemberSexStatisticsList() { | |
| 115 | + // TODO @疯狂:需要考虑,用户性别为空,则是“未知” | |
| 116 | + return memberStatisticsMapper.selectSummaryListBySex(); | |
| 117 | + } | |
| 118 | + | |
| 111 | 119 | } | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/pay/bo/RechargeSummaryRespBO.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.statistics.service.pay.bo; |
| 3 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 4 | import lombok.Data; |
| 5 | 5 | |
| 6 | +// TODO @疯狂:BO 不用写 swagger 注解哈,写注释就好啦; | |
| 6 | 7 | @Schema(description = "管理后台 - 充值统计 Response VO") |
| 7 | 8 | @Data |
| 8 | 9 | public class RechargeSummaryRespBO { | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeOrderStatisticsService.java
| ... | ... | @@ -22,6 +22,7 @@ public interface TradeOrderStatisticsService { |
| 22 | 22 | */ |
| 23 | 23 | TradeOrderSummaryRespBO getOrderSummary(LocalDateTime beginTime, LocalDateTime endTime); |
| 24 | 24 | |
| 25 | + // TODO 芋艿:已经 review | |
| 25 | 26 | /** |
| 26 | 27 | * 获取地区订单统计 |
| 27 | 28 | * |
| ... | ... | @@ -29,15 +30,17 @@ public interface TradeOrderStatisticsService { |
| 29 | 30 | */ |
| 30 | 31 | List<MemberAreaStatisticsRespVO> getSummaryListByAreaId(); |
| 31 | 32 | |
| 33 | + // TODO 芋艿:已经 review | |
| 32 | 34 | /** |
| 33 | 35 | * 获取下单用户数量 |
| 34 | 36 | * |
| 35 | 37 | * @param beginTime 起始时间 |
| 36 | 38 | * @param endTime 截止时间 |
| 37 | - * @return 支付下单数量 | |
| 39 | + * @return 下单用户数量 | |
| 38 | 40 | */ |
| 39 | 41 | Integer getOrderUserCount(LocalDateTime beginTime, LocalDateTime endTime); |
| 40 | 42 | |
| 43 | + // TODO 芋艿:已经 review | |
| 41 | 44 | /** |
| 42 | 45 | * 获取支付用户数量 |
| 43 | 46 | * |
| ... | ... | @@ -47,6 +50,7 @@ public interface TradeOrderStatisticsService { |
| 47 | 50 | */ |
| 48 | 51 | Integer getPayUserCount(LocalDateTime beginTime, LocalDateTime endTime); |
| 49 | 52 | |
| 53 | + // TODO 芋艿:已经 review | |
| 50 | 54 | /** |
| 51 | 55 | * 获取支付金额 |
| 52 | 56 | * | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeStatisticsService.java
yudao-module-mall/yudao-module-statistics-biz/src/main/resources/mapper/infra/ApiAccessLogStatisticsMapper.xml
| ... | ... | @@ -3,6 +3,7 @@ |
| 3 | 3 | <mapper namespace="cn.iocoder.yudao.module.statistics.dal.mysql.infra.ApiAccessLogStatisticsMapper"> |
| 4 | 4 | |
| 5 | 5 | <select id="selectCountByIp" resultType="java.lang.Integer"> |
| 6 | + <!-- TODO @疯狂:distinct 会不会更合适哈 --> | |
| 6 | 7 | SELECT COUNT(1) |
| 7 | 8 | FROM infra_api_access_log |
| 8 | 9 | WHERE create_time BETWEEN #{beginTime} AND #{endTime} |
| ... | ... | @@ -11,6 +12,7 @@ |
| 11 | 12 | </select> |
| 12 | 13 | |
| 13 | 14 | <select id="selectCountByUserId" resultType="java.lang.Integer"> |
| 15 | + <!-- TODO @疯狂:distinct 会不会更合适哈 --> | |
| 14 | 16 | SELECT COUNT(1) |
| 15 | 17 | FROM infra_api_access_log |
| 16 | 18 | WHERE user_id > 0 | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/resources/mapper/pay/PayWalletStatisticsMapper.xml
| ... | ... | @@ -31,6 +31,7 @@ |
| 31 | 31 | |
| 32 | 32 | <select id="selectRechargeSummaryGroupByWalletId" |
| 33 | 33 | resultType="cn.iocoder.yudao.module.statistics.service.pay.bo.RechargeSummaryRespBO"> |
| 34 | + <!-- TODO @疯狂:是不是不用 group by,而是通过 DISTINCT wallet_id 更合适哈? --> | |
| 34 | 35 | SELECT COUNT(1) AS rechargeUserCount, |
| 35 | 36 | SUM(pay_price) AS rechargePrice |
| 36 | 37 | FROM pay_wallet_recharge | ... | ... |
yudao-module-mall/yudao-module-statistics-biz/src/main/resources/mapper/trade/TradeStatisticsMapper.xml
| ... | ... | @@ -49,7 +49,7 @@ |
| 49 | 49 | <select id="selectExpensePriceByTimeBetween" resultType="java.lang.Integer"> |
| 50 | 50 | SELECT -- 支出金额 = 余额支付金额 + 支付佣金金额 + 商品退款金额 |
| 51 | 51 | SUM(order_wallet_pay_price + brokerage_settlement_price + after_sale_refund_price) AS expensePrice |
| 52 | - FROM trade_statistics | |
| 52 | + FROM trade_statistics | |
| 53 | 53 | WHERE deleted = FALSE |
| 54 | 54 | <if test="beginTime != null"> |
| 55 | 55 | AND time >= #{beginTime} | ... | ... |