mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 23:31:52 +08:00
统计:会员分析数据接口重构
This commit is contained in:
parent
8e35a786ba
commit
d3385dcb4f
@ -1,11 +1,16 @@
|
|||||||
package cn.iocoder.yudao.module.statistics.controller.admin.member;
|
package cn.iocoder.yudao.module.statistics.controller.admin.member;
|
||||||
|
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
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.TerminalEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
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.common.vo.DataComparisonRespVO;
|
||||||
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.*;
|
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.member.MemberStatisticsService;
|
||||||
|
import cn.iocoder.yudao.module.statistics.service.trade.TradeOrderStatisticsService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -16,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
@ -30,6 +36,10 @@ public class MemberStatisticsController {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private MemberStatisticsService memberStatisticsService;
|
private MemberStatisticsService memberStatisticsService;
|
||||||
|
@Resource
|
||||||
|
private TradeOrderStatisticsService tradeOrderStatisticsService;
|
||||||
|
@Resource
|
||||||
|
private ApiAccessLogStatisticsService apiAccessLogStatisticsService;
|
||||||
|
|
||||||
// TODO 芋艿:已经 review
|
// TODO 芋艿:已经 review
|
||||||
@GetMapping("/summary")
|
@GetMapping("/summary")
|
||||||
@ -44,8 +54,28 @@ public class MemberStatisticsController {
|
|||||||
@Operation(summary = "获得会员分析数据")
|
@Operation(summary = "获得会员分析数据")
|
||||||
@PreAuthorize("@ss.hasPermission('statistics:member:query')")
|
@PreAuthorize("@ss.hasPermission('statistics:member:query')")
|
||||||
public CommonResult<MemberAnalyseRespVO> getMemberAnalyse(MemberAnalyseReqVO reqVO) {
|
public CommonResult<MemberAnalyseRespVO> getMemberAnalyse(MemberAnalyseReqVO reqVO) {
|
||||||
return success(memberStatisticsService.getMemberAnalyse(
|
// 1. 查询数据
|
||||||
ArrayUtil.get(reqVO.getTimes(), 0), ArrayUtil.get(reqVO.getTimes(), 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
|
// TODO 芋艿:已经 review
|
||||||
|
@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.statistics.controller.admin.member.vo;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - 会员分析对照数据 Response VO")
|
@Schema(description = "管理后台 - 会员分析数据 Response VO")
|
||||||
@Data
|
@Data
|
||||||
public class MemberAnalyseComparisonRespVO {
|
public class MemberAnalyseDataRespVO {
|
||||||
|
|
||||||
@Schema(description = "会员数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "会员数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
private Integer registerUserCount;
|
private Integer registerUserCount;
|
@ -21,6 +21,6 @@ public class MemberAnalyseRespVO {
|
|||||||
private Integer atv;
|
private Integer atv;
|
||||||
|
|
||||||
@Schema(description = "对照数据", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "对照数据", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private DataComparisonRespVO<MemberAnalyseComparisonRespVO> comparison;
|
private DataComparisonRespVO<MemberAnalyseDataRespVO> comparison;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,9 @@ import cn.hutool.core.map.MapUtil;
|
|||||||
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.framework.ip.core.Area;
|
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.MemberAreaStatisticsRespVO;
|
||||||
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberSummaryRespVO;
|
import cn.iocoder.yudao.module.statistics.controller.admin.member.vo.MemberSummaryRespVO;
|
||||||
import cn.iocoder.yudao.module.statistics.service.pay.bo.RechargeSummaryRespBO;
|
import cn.iocoder.yudao.module.statistics.service.pay.bo.RechargeSummaryRespBO;
|
||||||
@ -28,7 +31,8 @@ public interface MemberStatisticsConvert {
|
|||||||
Map<Integer, Integer> userCountMap,
|
Map<Integer, Integer> userCountMap,
|
||||||
Map<Integer, MemberAreaStatisticsRespVO> orderMap) {
|
Map<Integer, MemberAreaStatisticsRespVO> orderMap) {
|
||||||
return CollectionUtils.convertList(areaList, area -> {
|
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()
|
return new MemberAreaStatisticsRespVO()
|
||||||
.setAreaId(area.getId()).setAreaName(area.getName())
|
.setAreaId(area.getId()).setAreaName(area.getName())
|
||||||
.setUserCount(MapUtil.getInt(userCountMap, area.getId(), 0))
|
.setUserCount(MapUtil.getInt(userCountMap, area.getId(), 0))
|
||||||
@ -40,4 +44,7 @@ public interface MemberStatisticsConvert {
|
|||||||
|
|
||||||
MemberSummaryRespVO convert(RechargeSummaryRespBO rechargeSummary, Integer expensePrice, Integer userCount);
|
MemberSummaryRespVO convert(RechargeSummaryRespBO rechargeSummary, Integer expensePrice, Integer userCount);
|
||||||
|
|
||||||
|
MemberAnalyseRespVO convert(Integer visitUserCount, Integer orderUserCount, Integer payUserCount, int atv,
|
||||||
|
DataComparisonRespVO<MemberAnalyseDataRespVO> comparison);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,15 +21,15 @@ public interface MemberStatisticsService {
|
|||||||
*/
|
*/
|
||||||
MemberSummaryRespVO getMemberSummary();
|
MemberSummaryRespVO getMemberSummary();
|
||||||
|
|
||||||
// TODO 芋艿:已经 review
|
|
||||||
/**
|
/**
|
||||||
* 获取用户分析数据
|
* 获取会员分析对照数据
|
||||||
*
|
*
|
||||||
* @param beginTime 起始时间
|
* @param beginTime 起始时间
|
||||||
* @param endTime 截止时间
|
* @param endTime 截止时间
|
||||||
* @return 用户分析数据
|
* @return 会员分析对照数据
|
||||||
*/
|
*/
|
||||||
MemberAnalyseRespVO getMemberAnalyse(LocalDateTime beginTime, LocalDateTime endTime);
|
DataComparisonRespVO<MemberAnalyseDataRespVO> getMemberAnalyseComparisonData(LocalDateTime beginTime,
|
||||||
|
LocalDateTime endTime);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按照省份,获得会员统计列表
|
* 按照省份,获得会员统计列表
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.statistics.service.member;
|
package cn.iocoder.yudao.module.statistics.service.member;
|
||||||
|
|
||||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
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.common.enums.UserTypeEnum;
|
||||||
import cn.iocoder.yudao.framework.ip.core.Area;
|
import cn.iocoder.yudao.framework.ip.core.Area;
|
||||||
import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
|
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);
|
return MemberStatisticsConvert.INSTANCE.convertList(areaList, userCountMap, orderMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @疯狂:这个方法,要不拆成:1)controller 调用 getMemberAnalyseComparisonData;2)tradeOrderStatisticsService.getPayUserCount;3)tradeOrderStatisticsService.getOrderPayPrice;4)。。。
|
|
||||||
// TODO 就是说:分析交给 controller 去组合;
|
|
||||||
@Override
|
@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);
|
LocalDateTime referenceEndDate = beginTime.minusDays(1); // 减少1天,防止出现时间重叠
|
||||||
// TODO @疯狂:如果时间段这么处理,会不会 beginTime 重叠了。因为是 <= 一个时间;如果数据库插入的是 ,xxxx-yy-zz 00:00:00 的话,它既满足 >= ? 也满足 <= ;(如果不好理解,微信聊)
|
LocalDateTime referenceBeginDate = referenceEndDate.minus(Duration.between(beginTime, endTime));
|
||||||
LocalDateTime referenceBeginTime = beginTime.minus(Duration.between(beginTime, endTime));
|
MemberAnalyseDataRespVO reference = getMemberAnalyseData(
|
||||||
MemberAnalyseComparisonRespVO reference = getMemberAnalyseComparisonData(referenceBeginTime, beginTime);
|
LocalDateTimeUtil.beginOfDay(referenceBeginDate), LocalDateTimeUtil.endOfDay(referenceEndDate));
|
||||||
|
return new DataComparisonRespVO<>(vo, reference);
|
||||||
// 计算客单价
|
|
||||||
// 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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MemberAnalyseComparisonRespVO getMemberAnalyseComparisonData(LocalDateTime beginTime, LocalDateTime endTime) {
|
private MemberAnalyseDataRespVO getMemberAnalyseData(LocalDateTime beginTime, LocalDateTime endTime) {
|
||||||
Integer rechargeUserCount = Optional.ofNullable(payWalletStatisticsService.getUserRechargeSummary(beginTime, endTime))
|
Integer rechargeUserCount = Optional.ofNullable(payWalletStatisticsService.getUserRechargeSummary(beginTime, endTime))
|
||||||
.map(RechargeSummaryRespBO::getRechargeUserCount).orElse(0);
|
.map(RechargeSummaryRespBO::getRechargeUserCount).orElse(0);
|
||||||
return new MemberAnalyseComparisonRespVO()
|
return new MemberAnalyseDataRespVO()
|
||||||
.setRegisterUserCount(memberStatisticsMapper.selectUserCount(beginTime, endTime))
|
.setRegisterUserCount(memberStatisticsMapper.selectUserCount(beginTime, endTime))
|
||||||
.setVisitUserCount(apiAccessLogStatisticsService.getUserCount(UserTypeEnum.MEMBER.getValue(), beginTime, endTime))
|
.setVisitUserCount(apiAccessLogStatisticsService.getUserCount(UserTypeEnum.MEMBER.getValue(), beginTime, endTime))
|
||||||
.setRechargeUserCount(rechargeUserCount);
|
.setRechargeUserCount(rechargeUserCount);
|
||||||
|
Loading…
Reference in New Issue
Block a user