|
@@ -4,15 +4,11 @@ import cn.hutool.core.collection.CollUtil;
|
|
import cn.hutool.core.util.ObjUtil;
|
|
import cn.hutool.core.util.ObjUtil;
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
|
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
|
-import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticBusinessEndStatusRespVO;
|
|
|
|
-import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticFunnelRespVO;
|
|
|
|
-import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO;
|
|
|
|
-import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO;
|
|
|
|
|
|
+import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.*;
|
|
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
|
|
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
|
|
import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsFunnelMapper;
|
|
import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsFunnelMapper;
|
|
import cn.iocoder.yudao.module.crm.enums.business.CrmBusinessEndStatusEnum;
|
|
import cn.iocoder.yudao.module.crm.enums.business.CrmBusinessEndStatusEnum;
|
|
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
|
|
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
|
|
-import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
|
|
|
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
|
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
|
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
|
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|
@@ -22,14 +18,10 @@ import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
-import java.time.format.DateTimeFormatter;
|
|
|
|
import java.util.Collections;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
-import java.util.Map;
|
|
|
|
-import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
|
|
|
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
|
|
|
|
|
|
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
|
|
|
|
|
/**
|
|
/**
|
|
* CRM 销售漏斗分析 Service 实现类
|
|
* CRM 销售漏斗分析 Service 实现类
|
|
@@ -45,15 +37,12 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic
|
|
@Resource
|
|
@Resource
|
|
private AdminUserApi adminUserApi;
|
|
private AdminUserApi adminUserApi;
|
|
@Resource
|
|
@Resource
|
|
- private CrmCustomerService customerService;
|
|
|
|
- @Resource
|
|
|
|
private CrmBusinessService businessService;
|
|
private CrmBusinessService businessService;
|
|
@Resource
|
|
@Resource
|
|
private DeptApi deptApi;
|
|
private DeptApi deptApi;
|
|
|
|
|
|
- // TODO @puhui999:貌似想了下,可能还是得按照;;;
|
|
|
|
@Override
|
|
@Override
|
|
- public CrmStatisticFunnelRespVO getFunnelSummary(CrmStatisticsFunnelReqVO reqVO) {
|
|
|
|
|
|
+ public CrmStatisticFunnelSummaryRespVO getFunnelSummary(CrmStatisticsFunnelReqVO reqVO) {
|
|
// 1. 获得用户编号数组
|
|
// 1. 获得用户编号数组
|
|
List<Long> userIds = getUserIds(reqVO);
|
|
List<Long> userIds = getUserIds(reqVO);
|
|
if (CollUtil.isEmpty(userIds)) {
|
|
if (CollUtil.isEmpty(userIds)) {
|
|
@@ -62,34 +51,22 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic
|
|
reqVO.setUserIds(userIds);
|
|
reqVO.setUserIds(userIds);
|
|
|
|
|
|
// 2. 获得漏斗数据
|
|
// 2. 获得漏斗数据
|
|
- return new CrmStatisticFunnelRespVO(
|
|
|
|
- customerService.getCustomerCountByOwnerUserIds(userIds, reqVO.getTimes()),
|
|
|
|
- businessService.getBusinessCountByOwnerUserIdsAndEndStatus(userIds, reqVO.getTimes(), null),
|
|
|
|
- businessService.getBusinessCountByOwnerUserIdsAndEndStatus(userIds, reqVO.getTimes(), CrmBusinessEndStatusEnum.WIN.getStatus())
|
|
|
|
- );
|
|
|
|
|
|
+ Long customerCount = funnelMapper.selectCustomerCountByDate(reqVO);
|
|
|
|
+ Long businessCount = funnelMapper.selectBusinessCountByDateAndEndStatus(reqVO, null);
|
|
|
|
+ Long businessWinCount = funnelMapper.selectBusinessCountByDateAndEndStatus(reqVO, CrmBusinessEndStatusEnum.WIN.getStatus());
|
|
|
|
+ return new CrmStatisticFunnelSummaryRespVO(customerCount, businessCount, businessWinCount);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- public List<CrmStatisticBusinessEndStatusRespVO> getBusinessEndStatusSummary(CrmStatisticsFunnelReqVO reqVO) {
|
|
|
|
|
|
+ public List<CrmStatisticsBusinessSummaryByEndStatusRespVO> getBusinessSummaryByEndStatus(CrmStatisticsFunnelReqVO reqVO) {
|
|
// 1. 获得用户编号数组
|
|
// 1. 获得用户编号数组
|
|
reqVO.setUserIds(getUserIds(reqVO));
|
|
reqVO.setUserIds(getUserIds(reqVO));
|
|
if (CollUtil.isEmpty(reqVO.getUserIds())) {
|
|
if (CollUtil.isEmpty(reqVO.getUserIds())) {
|
|
return Collections.emptyList();
|
|
return Collections.emptyList();
|
|
}
|
|
}
|
|
|
|
|
|
- // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算;
|
|
|
|
- // 2.1 获得用户负责的商机
|
|
|
|
- List<CrmBusinessDO> businessList = businessService.getBusinessListByOwnerUserIdsAndEndStatusNotNull(reqVO.getUserIds(), reqVO.getTimes());
|
|
|
|
- // 2.2 统计各阶段数据
|
|
|
|
- Map<Integer, List<CrmBusinessDO>> businessMap = convertMultiMap(businessList, CrmBusinessDO::getEndStatus);
|
|
|
|
- return convertList(CrmBusinessEndStatusEnum.values(), endStatusEnum -> {
|
|
|
|
- List<CrmBusinessDO> list = businessMap.get(endStatusEnum.getStatus());
|
|
|
|
- if (CollUtil.isEmpty(list)) {
|
|
|
|
- return new CrmStatisticBusinessEndStatusRespVO(endStatusEnum.getStatus(), 0L, BigDecimal.ZERO);
|
|
|
|
- }
|
|
|
|
- return new CrmStatisticBusinessEndStatusRespVO(endStatusEnum.getStatus(), (long) list.size(),
|
|
|
|
- getSumValue(list, CrmBusinessDO::getTotalPrice, BigDecimal::add));
|
|
|
|
- });
|
|
|
|
|
|
+ // 2. 获得统计数据
|
|
|
|
+ return funnelMapper.selectBusinessSummaryListGroupByEndStatus(reqVO);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -101,26 +78,45 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic
|
|
}
|
|
}
|
|
|
|
|
|
// 2. 按天统计,获取分项统计数据
|
|
// 2. 按天统计,获取分项统计数据
|
|
- // TODO @puhui999:可以这个统计,返回的时候,就把数量、金额一起统计好;
|
|
|
|
- List<CrmStatisticsBusinessSummaryByDateRespVO> businessCreateCountList = funnelMapper.selectBusinessCreateCountGroupByDate(reqVO);
|
|
|
|
- List<CrmBusinessDO> businessList = businessService.getBusinessListByOwnerUserIdsAndDate(reqVO.getUserIds(), reqVO.getTimes());
|
|
|
|
- Map<String, BigDecimal> businessDealCountMap = businessList.stream().collect(Collectors.groupingBy(business ->
|
|
|
|
- business.getCreateTime().format(DateTimeFormatter.ofPattern(FORMAT_YEAR_MONTH_DAY)),
|
|
|
|
- Collectors.reducing(BigDecimal.ZERO, CrmBusinessDO::getTotalPrice, BigDecimal::add)));
|
|
|
|
-
|
|
|
|
|
|
+ List<CrmStatisticsBusinessSummaryByDateRespVO> businessSummaryList = funnelMapper.selectBusinessSummaryGroupByDate(reqVO);
|
|
// 3. 按照日期间隔,合并数据
|
|
// 3. 按照日期间隔,合并数据
|
|
List<LocalDateTime[]> timeRanges = LocalDateTimeUtils.getDateRangeList(reqVO.getTimes()[0], reqVO.getTimes()[1], reqVO.getInterval());
|
|
List<LocalDateTime[]> timeRanges = LocalDateTimeUtils.getDateRangeList(reqVO.getTimes()[0], reqVO.getTimes()[1], reqVO.getInterval());
|
|
return convertList(timeRanges, times -> {
|
|
return convertList(timeRanges, times -> {
|
|
- Integer businessCreateCount = businessCreateCountList.stream()
|
|
|
|
|
|
+ Long businessCreateCount = businessSummaryList.stream()
|
|
.filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime()))
|
|
.filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime()))
|
|
- .mapToInt(CrmStatisticsBusinessSummaryByDateRespVO::getBusinessCreateCount).sum();
|
|
|
|
- BigDecimal businessDealCount = businessDealCountMap.entrySet().stream()
|
|
|
|
- .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getKey()))
|
|
|
|
- .map(Map.Entry::getValue)
|
|
|
|
|
|
+ .mapToLong(CrmStatisticsBusinessSummaryByDateRespVO::getBusinessCreateCount).sum();
|
|
|
|
+ BigDecimal businessDealCount = businessSummaryList.stream()
|
|
|
|
+ .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime()))
|
|
|
|
+ .map(CrmStatisticsBusinessSummaryByDateRespVO::getTotalPrice)
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
return new CrmStatisticsBusinessSummaryByDateRespVO()
|
|
return new CrmStatisticsBusinessSummaryByDateRespVO()
|
|
.setTime(LocalDateTimeUtils.formatDateRange(times[0], times[1], reqVO.getInterval()))
|
|
.setTime(LocalDateTimeUtils.formatDateRange(times[0], times[1], reqVO.getInterval()))
|
|
- .setBusinessCreateCount(businessCreateCount).setBusinessDealCount(businessDealCount);
|
|
|
|
|
|
+ .setBusinessCreateCount(businessCreateCount).setTotalPrice(businessDealCount);
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<CrmStatisticsBusinessInversionRateSummaryByDateRespVO> getBusinessInversionRateSummaryByDate(CrmStatisticsFunnelReqVO reqVO) {
|
|
|
|
+ // 1. 获得用户编号数组
|
|
|
|
+ reqVO.setUserIds(getUserIds(reqVO));
|
|
|
|
+ if (CollUtil.isEmpty(reqVO.getUserIds())) {
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 2. 按天统计,获取分项统计数据
|
|
|
|
+ List<CrmStatisticsBusinessInversionRateSummaryByDateRespVO> businessSummaryList = funnelMapper.selectBusinessInversionRateSummaryByDate(reqVO);
|
|
|
|
+ // 3. 按照日期间隔,合并数据
|
|
|
|
+ List<LocalDateTime[]> timeRanges = LocalDateTimeUtils.getDateRangeList(reqVO.getTimes()[0], reqVO.getTimes()[1], reqVO.getInterval());
|
|
|
|
+ return convertList(timeRanges, times -> {
|
|
|
|
+ Long businessCount = businessSummaryList.stream()
|
|
|
|
+ .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime()))
|
|
|
|
+ .mapToLong(CrmStatisticsBusinessInversionRateSummaryByDateRespVO::getBusinessCount).sum();
|
|
|
|
+ Long businessWinCount = businessSummaryList.stream()
|
|
|
|
+ .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime()))
|
|
|
|
+ .mapToLong(CrmStatisticsBusinessInversionRateSummaryByDateRespVO::getBusinessWinCount).sum();
|
|
|
|
+ return new CrmStatisticsBusinessInversionRateSummaryByDateRespVO()
|
|
|
|
+ .setTime(LocalDateTimeUtils.formatDateRange(times[0], times[1], reqVO.getInterval()))
|
|
|
|
+ .setBusinessCount(businessCount).setBusinessWinCount(businessWinCount);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -132,7 +128,7 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic
|
|
return PageResult.empty();
|
|
return PageResult.empty();
|
|
}
|
|
}
|
|
// 2. 执行查询
|
|
// 2. 执行查询
|
|
- return businessService.getBusinessPageByDate(pageVO.getUserIds(), pageVO.getTimes(), pageVO.getPageNo(), pageVO.getPageSize());
|
|
|
|
|
|
+ return businessService.getBusinessPageByDate(pageVO);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|