Commit ed5f3a6bc2031a5eedf6be32e0a3fe0f3f156813
1 parent
0eff2ae6
crm:code review 销售漏斗
Showing
13 changed files
with
38 additions
and
82 deletions
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java
| @@ -177,7 +177,7 @@ public class CrmBusinessController { | @@ -177,7 +177,7 @@ public class CrmBusinessController { | ||
| 177 | buildBusinessDetailList(list)); | 177 | buildBusinessDetailList(list)); |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | - private List<CrmBusinessRespVO> buildBusinessDetailList(List<CrmBusinessDO> list) { | 180 | + public List<CrmBusinessRespVO> buildBusinessDetailList(List<CrmBusinessDO> list) { |
| 181 | if (CollUtil.isEmpty(list)) { | 181 | if (CollUtil.isEmpty(list)) { |
| 182 | return Collections.emptyList(); | 182 | return Collections.emptyList(); |
| 183 | } | 183 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsFunnelController.java
| 1 | package cn.iocoder.yudao.module.crm.controller.admin.statistics; | 1 | package cn.iocoder.yudao.module.crm.controller.admin.statistics; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.collection.CollUtil; | 3 | +import cn.hutool.extra.spring.SpringUtil; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | ||
| 7 | -import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | ||
| 8 | -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 6 | +import cn.iocoder.yudao.module.crm.controller.admin.business.CrmBusinessController; |
| 9 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO; | 7 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO; |
| 10 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticBusinessEndStatusRespVO; | 8 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticBusinessEndStatusRespVO; |
| 11 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticFunnelRespVO; | 9 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticFunnelRespVO; |
| 12 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO; | 10 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO; |
| 13 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; | 11 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; |
| 14 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; | 12 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; |
| 15 | -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; | ||
| 16 | -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; | ||
| 17 | -import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; | ||
| 18 | -import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; | ||
| 19 | -import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusService; | ||
| 20 | -import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; | ||
| 21 | import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsFunnelService; | 13 | import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsFunnelService; |
| 22 | -import cn.iocoder.yudao.module.system.api.dept.DeptApi; | ||
| 23 | -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; | ||
| 24 | -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | ||
| 25 | -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | ||
| 26 | import io.swagger.v3.oas.annotations.Operation; | 14 | import io.swagger.v3.oas.annotations.Operation; |
| 27 | import io.swagger.v3.oas.annotations.tags.Tag; | 15 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 28 | import jakarta.annotation.Resource; | 16 | import jakarta.annotation.Resource; |
| @@ -33,14 +21,9 @@ import org.springframework.web.bind.annotation.GetMapping; | @@ -33,14 +21,9 @@ import org.springframework.web.bind.annotation.GetMapping; | ||
| 33 | import org.springframework.web.bind.annotation.RequestMapping; | 21 | import org.springframework.web.bind.annotation.RequestMapping; |
| 34 | import org.springframework.web.bind.annotation.RestController; | 22 | import org.springframework.web.bind.annotation.RestController; |
| 35 | 23 | ||
| 36 | -import java.util.Collections; | ||
| 37 | import java.util.List; | 24 | import java.util.List; |
| 38 | -import java.util.Map; | ||
| 39 | -import java.util.stream.Stream; | ||
| 40 | 25 | ||
| 41 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 26 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 42 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap; | ||
| 43 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | ||
| 44 | 27 | ||
| 45 | @Tag(name = "管理后台 - CRM 销售漏斗") | 28 | @Tag(name = "管理后台 - CRM 销售漏斗") |
| 46 | @RestController | 29 | @RestController |
| @@ -48,31 +31,20 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. | @@ -48,31 +31,20 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. | ||
| 48 | @Validated | 31 | @Validated |
| 49 | public class CrmStatisticsFunnelController { | 32 | public class CrmStatisticsFunnelController { |
| 50 | 33 | ||
| 34 | + // TODO @puhui999:crmStatisticsFunnelService 改成 funnelService 更好点哈 | ||
| 51 | @Resource | 35 | @Resource |
| 52 | private CrmStatisticsFunnelService crmStatisticsFunnelService; | 36 | private CrmStatisticsFunnelService crmStatisticsFunnelService; |
| 53 | - @Resource | ||
| 54 | - private CrmBusinessService businessService; | ||
| 55 | - @Resource | ||
| 56 | - private CrmCustomerService customerService; | ||
| 57 | - @Resource | ||
| 58 | - private CrmBusinessStatusService businessStatusTypeService; | ||
| 59 | - @Resource | ||
| 60 | - private CrmBusinessStatusService businessStatusService; | ||
| 61 | - | ||
| 62 | - @Resource | ||
| 63 | - private AdminUserApi adminUserApi; | ||
| 64 | - @Resource | ||
| 65 | - private DeptApi deptApi; | ||
| 66 | 37 | ||
| 67 | @GetMapping("/get-funnel-summary") | 38 | @GetMapping("/get-funnel-summary") |
| 68 | - @Operation(summary = "获取销售漏斗统计数据", description = "用于【销售漏斗】页面") | 39 | + @Operation(summary = "获取销售漏斗统计数据", description = "用于【销售漏斗】页面的【销售漏斗分析】") |
| 69 | @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')") | 40 | @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')") |
| 70 | public CommonResult<CrmStatisticFunnelRespVO> getFunnelSummary(@Valid CrmStatisticsFunnelReqVO reqVO) { | 41 | public CommonResult<CrmStatisticFunnelRespVO> getFunnelSummary(@Valid CrmStatisticsFunnelReqVO reqVO) { |
| 71 | return success(crmStatisticsFunnelService.getFunnelSummary(reqVO)); | 42 | return success(crmStatisticsFunnelService.getFunnelSummary(reqVO)); |
| 72 | } | 43 | } |
| 73 | 44 | ||
| 45 | + // TODO @puhui:这个接口,应该是 getBusinessSummaryByEndStatus?这样更统一哈; | ||
| 74 | @GetMapping("/get-business-end-status-summary") | 46 | @GetMapping("/get-business-end-status-summary") |
| 75 | - @Operation(summary = "获取商机结束状态统计", description = "用于【销售漏斗】页面") | 47 | + @Operation(summary = "获取商机结束状态统计", description = "用于【销售漏斗】页面的【销售漏斗分析】") |
| 76 | @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')") | 48 | @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')") |
| 77 | public CommonResult<List<CrmStatisticBusinessEndStatusRespVO>> getBusinessEndStatusSummary(@Valid CrmStatisticsFunnelReqVO reqVO) { | 49 | public CommonResult<List<CrmStatisticBusinessEndStatusRespVO>> getBusinessEndStatusSummary(@Valid CrmStatisticsFunnelReqVO reqVO) { |
| 78 | return success(crmStatisticsFunnelService.getBusinessEndStatusSummary(reqVO)); | 50 | return success(crmStatisticsFunnelService.getBusinessEndStatusSummary(reqVO)); |
| @@ -86,7 +58,7 @@ public class CrmStatisticsFunnelController { | @@ -86,7 +58,7 @@ public class CrmStatisticsFunnelController { | ||
| 86 | } | 58 | } |
| 87 | 59 | ||
| 88 | @GetMapping("/get-business-page-by-date") | 60 | @GetMapping("/get-business-page-by-date") |
| 89 | - @Operation(summary = "获得商机分页(按日期)", description = "用于【销售漏斗】页面") | 61 | + @Operation(summary = "获得商机分页(按日期)", description = "用于【销售漏斗】页面的【新增商机分析】") |
| 90 | @PreAuthorize("@ss.hasPermission('crm:business:query')") | 62 | @PreAuthorize("@ss.hasPermission('crm:business:query')") |
| 91 | public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByDate(@Valid CrmStatisticsFunnelReqVO pageVO) { | 63 | public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByDate(@Valid CrmStatisticsFunnelReqVO pageVO) { |
| 92 | PageResult<CrmBusinessDO> pageResult = crmStatisticsFunnelService.getBusinessPageByDate(pageVO); | 64 | PageResult<CrmBusinessDO> pageResult = crmStatisticsFunnelService.getBusinessPageByDate(pageVO); |
| @@ -94,37 +66,7 @@ public class CrmStatisticsFunnelController { | @@ -94,37 +66,7 @@ public class CrmStatisticsFunnelController { | ||
| 94 | } | 66 | } |
| 95 | 67 | ||
| 96 | private List<CrmBusinessRespVO> buildBusinessDetailList(List<CrmBusinessDO> list) { | 68 | private List<CrmBusinessRespVO> buildBusinessDetailList(List<CrmBusinessDO> list) { |
| 97 | - if (CollUtil.isEmpty(list)) { | ||
| 98 | - return Collections.emptyList(); | ||
| 99 | - } | ||
| 100 | - // 1.1 获取客户列表 | ||
| 101 | - Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap( | ||
| 102 | - convertSet(list, CrmBusinessDO::getCustomerId)); | ||
| 103 | - // 1.2 获取创建人、负责人列表 | ||
| 104 | - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(list, | ||
| 105 | - contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); | ||
| 106 | - Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); | ||
| 107 | - // 1.3 获得商机状态组 | ||
| 108 | - Map<Long, CrmBusinessStatusTypeDO> statusTypeMap = businessStatusTypeService.getBusinessStatusTypeMap( | ||
| 109 | - convertSet(list, CrmBusinessDO::getStatusTypeId)); | ||
| 110 | - Map<Long, CrmBusinessStatusDO> statusMap = businessStatusService.getBusinessStatusMap( | ||
| 111 | - convertSet(list, CrmBusinessDO::getStatusId)); | ||
| 112 | - // 2. 拼接数据 | ||
| 113 | - return BeanUtils.toBean(list, CrmBusinessRespVO.class, businessVO -> { | ||
| 114 | - // 2.1 设置客户名称 | ||
| 115 | - MapUtils.findAndThen(customerMap, businessVO.getCustomerId(), customer -> businessVO.setCustomerName(customer.getName())); | ||
| 116 | - // 2.2 设置创建人、负责人名称 | ||
| 117 | - MapUtils.findAndThen(userMap, NumberUtils.parseLong(businessVO.getCreator()), | ||
| 118 | - user -> businessVO.setCreatorName(user.getNickname())); | ||
| 119 | - MapUtils.findAndThen(userMap, businessVO.getOwnerUserId(), user -> { | ||
| 120 | - businessVO.setOwnerUserName(user.getNickname()); | ||
| 121 | - MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> businessVO.setOwnerUserDeptName(dept.getName())); | ||
| 122 | - }); | ||
| 123 | - // 2.3 设置商机状态 | ||
| 124 | - MapUtils.findAndThen(statusTypeMap, businessVO.getStatusTypeId(), statusType -> businessVO.setStatusTypeName(statusType.getName())); | ||
| 125 | - MapUtils.findAndThen(statusMap, businessVO.getStatusId(), status -> businessVO.setStatusName( | ||
| 126 | - businessService.getBusinessStatusName(businessVO.getEndStatus(), status))); | ||
| 127 | - }); | 69 | + return SpringUtil.getBean(CrmBusinessController.class).buildBusinessDetailList(list); |
| 128 | } | 70 | } |
| 129 | 71 | ||
| 130 | } | 72 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticBusinessEndStatusRespVO.java
| @@ -7,6 +7,7 @@ import lombok.NoArgsConstructor; | @@ -7,6 +7,7 @@ import lombok.NoArgsConstructor; | ||
| 7 | 7 | ||
| 8 | import java.math.BigDecimal; | 8 | import java.math.BigDecimal; |
| 9 | 9 | ||
| 10 | +// TODO @puhui999:改成 CrmStatisticsBusinessSummaryByEndStatusRespVO,按照结束状态 | ||
| 10 | @Schema(description = "管理后台 - CRM 商机结束状态统计 Response VO") | 11 | @Schema(description = "管理后台 - CRM 商机结束状态统计 Response VO") |
| 11 | @NoArgsConstructor | 12 | @NoArgsConstructor |
| 12 | @AllArgsConstructor | 13 | @AllArgsConstructor |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticFunnelRespVO.java
| @@ -5,6 +5,7 @@ import lombok.AllArgsConstructor; | @@ -5,6 +5,7 @@ import lombok.AllArgsConstructor; | ||
| 5 | import lombok.Data; | 5 | import lombok.Data; |
| 6 | import lombok.NoArgsConstructor; | 6 | import lombok.NoArgsConstructor; |
| 7 | 7 | ||
| 8 | +// TODO @puhui999:改成 CrmStatisticFunnelSummaryRespVO 更有统计的味道 | ||
| 8 | @Schema(description = "管理后台 - CRM 销售漏斗 Response VO") | 9 | @Schema(description = "管理后台 - CRM 销售漏斗 Response VO") |
| 9 | @NoArgsConstructor | 10 | @NoArgsConstructor |
| 10 | @AllArgsConstructor | 11 | @AllArgsConstructor |
| @@ -17,6 +18,7 @@ public class CrmStatisticFunnelRespVO { | @@ -17,6 +18,7 @@ public class CrmStatisticFunnelRespVO { | ||
| 17 | @Schema(description = "商机数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 18 | @Schema(description = "商机数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 18 | private Long businessCount; | 19 | private Long businessCount; |
| 19 | 20 | ||
| 21 | + // TODO @puhui999:这个改成 businessWinCount 可能会更合适点哈; | ||
| 20 | @Schema(description = "赢单数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 22 | @Schema(description = "赢单数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 21 | private Long winCount; | 23 | private Long winCount; |
| 22 | 24 |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticsBusinessRespVO.java
| @@ -3,14 +3,12 @@ package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel; | @@ -3,14 +3,12 @@ package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel; | ||
| 3 | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; | 3 | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| 4 | import com.alibaba.excel.annotation.ExcelProperty; | 4 | import com.alibaba.excel.annotation.ExcelProperty; |
| 5 | import io.swagger.v3.oas.annotations.media.Schema; | 5 | import io.swagger.v3.oas.annotations.media.Schema; |
| 6 | -import lombok.AllArgsConstructor; | ||
| 7 | import lombok.Data; | 6 | import lombok.Data; |
| 8 | -import lombok.NoArgsConstructor; | ||
| 9 | 7 | ||
| 10 | import java.math.BigDecimal; | 8 | import java.math.BigDecimal; |
| 11 | import java.time.LocalDateTime; | 9 | import java.time.LocalDateTime; |
| 12 | -import java.util.List; | ||
| 13 | 10 | ||
| 11 | +// TODO @puhui999:是不是可以删除哈? | ||
| 14 | @Schema(description = "管理后台 - CRM 商机 Response VO") | 12 | @Schema(description = "管理后台 - CRM 商机 Response VO") |
| 15 | @Data | 13 | @Data |
| 16 | @ExcelIgnoreUnannotated | 14 | @ExcelIgnoreUnannotated |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticsBusinessSummaryByDateRespVO.java
| @@ -15,6 +15,7 @@ public class CrmStatisticsBusinessSummaryByDateRespVO { | @@ -15,6 +15,7 @@ public class CrmStatisticsBusinessSummaryByDateRespVO { | ||
| 15 | @Schema(description = "新增商机数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 15 | @Schema(description = "新增商机数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 16 | private Integer businessCreateCount; | 16 | private Integer businessCreateCount; |
| 17 | 17 | ||
| 18 | + // TODO @puhui999:是不是金额哈,不是数量 | ||
| 18 | @Schema(description = "新增商机金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 19 | @Schema(description = "新增商机金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 19 | private BigDecimal businessDealCount; | 20 | private BigDecimal businessDealCount; |
| 20 | 21 |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticsFunnelReqVO.java
| @@ -17,6 +17,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ | @@ -17,6 +17,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ | ||
| 17 | 17 | ||
| 18 | @Schema(description = "管理后台 - CRM 销售漏斗 Request VO") | 18 | @Schema(description = "管理后台 - CRM 销售漏斗 Request VO") |
| 19 | @Data | 19 | @Data |
| 20 | +// TODO @puhui999:不用写 EqualsAndHashCode、ToString,已经全局 lombok 啦 | ||
| 20 | @EqualsAndHashCode(callSuper = true) | 21 | @EqualsAndHashCode(callSuper = true) |
| 21 | @ToString(callSuper = true) | 22 | @ToString(callSuper = true) |
| 22 | public class CrmStatisticsFunnelReqVO extends PageParam { | 23 | public class CrmStatisticsFunnelReqVO extends PageParam { |
| @@ -42,6 +43,7 @@ public class CrmStatisticsFunnelReqVO extends PageParam { | @@ -42,6 +43,7 @@ public class CrmStatisticsFunnelReqVO extends PageParam { | ||
| 42 | @InEnum(value = DateIntervalEnum.class, message = "时间间隔类型,必须是 {value}") | 43 | @InEnum(value = DateIntervalEnum.class, message = "时间间隔类型,必须是 {value}") |
| 43 | private Integer interval; | 44 | private Integer interval; |
| 44 | 45 | ||
| 46 | + // TODO @puhui999:这个全部前端传递哈;参考 CrmStatisticsCustomerReqVO | ||
| 45 | /** | 47 | /** |
| 46 | * 前端如果选择自定义时间, 那么前端传递起始-终止时间, 如果选择其他时间间隔类型, 则由后台计算起始-终止时间 | 48 | * 前端如果选择自定义时间, 那么前端传递起始-终止时间, 如果选择其他时间间隔类型, 则由后台计算起始-终止时间 |
| 47 | * 并作为参数传递给Mapper | 49 | * 并作为参数传递给Mapper |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java
| @@ -73,6 +73,7 @@ public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> { | @@ -73,6 +73,7 @@ public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> { | ||
| 73 | .betweenIfPresent(CrmBusinessDO::getCreateTime, times)); | 73 | .betweenIfPresent(CrmBusinessDO::getCreateTime, times)); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | + // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 76 | default List<CrmBusinessDO> selectListByOwnerUserIdsAndEndStatusNotNull(Collection<Long> ownerUserIds, LocalDateTime[] times) { | 77 | default List<CrmBusinessDO> selectListByOwnerUserIdsAndEndStatusNotNull(Collection<Long> ownerUserIds, LocalDateTime[] times) { |
| 77 | return selectList(new LambdaQueryWrapperX<CrmBusinessDO>() | 78 | return selectList(new LambdaQueryWrapperX<CrmBusinessDO>() |
| 78 | .in(CrmBusinessDO::getOwnerUserId, ownerUserIds) | 79 | .in(CrmBusinessDO::getOwnerUserId, ownerUserIds) |
| @@ -80,6 +81,7 @@ public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> { | @@ -80,6 +81,7 @@ public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> { | ||
| 80 | .isNotNull(CrmBusinessDO::getEndStatus)); | 81 | .isNotNull(CrmBusinessDO::getEndStatus)); |
| 81 | } | 82 | } |
| 82 | 83 | ||
| 84 | + // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 83 | default List<CrmBusinessDO> selectListByOwnerUserIdsAndDate(Collection<Long> ownerUserIds, LocalDateTime[] times) { | 85 | default List<CrmBusinessDO> selectListByOwnerUserIdsAndDate(Collection<Long> ownerUserIds, LocalDateTime[] times) { |
| 84 | return selectList(new LambdaQueryWrapperX<CrmBusinessDO>() | 86 | return selectList(new LambdaQueryWrapperX<CrmBusinessDO>() |
| 85 | .in(CrmBusinessDO::getOwnerUserId, ownerUserIds) | 87 | .in(CrmBusinessDO::getOwnerUserId, ownerUserIds) |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java
| @@ -19,11 +19,9 @@ import org.apache.ibatis.annotations.Mapper; | @@ -19,11 +19,9 @@ import org.apache.ibatis.annotations.Mapper; | ||
| 19 | import org.springframework.lang.Nullable; | 19 | import org.springframework.lang.Nullable; |
| 20 | import org.springframework.util.Assert; | 20 | import org.springframework.util.Assert; |
| 21 | 21 | ||
| 22 | -import javax.management.ObjectName; | ||
| 23 | import java.time.LocalDateTime; | 22 | import java.time.LocalDateTime; |
| 24 | import java.util.Collection; | 23 | import java.util.Collection; |
| 25 | import java.util.List; | 24 | import java.util.List; |
| 26 | -import java.util.Set; | ||
| 27 | 25 | ||
| 28 | /** | 26 | /** |
| 29 | * 客户 Mapper | 27 | * 客户 Mapper |
| @@ -188,6 +186,7 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> { | @@ -188,6 +186,7 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> { | ||
| 188 | return selectCount(query); | 186 | return selectCount(query); |
| 189 | } | 187 | } |
| 190 | 188 | ||
| 189 | + // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 191 | default Long selectCountByOwnerUserIds(Collection<Long> ownerUserIds, LocalDateTime[] times){ | 190 | default Long selectCountByOwnerUserIds(Collection<Long> ownerUserIds, LocalDateTime[] times){ |
| 192 | return selectCount(new LambdaQueryWrapperX<CrmCustomerDO>() | 191 | return selectCount(new LambdaQueryWrapperX<CrmCustomerDO>() |
| 193 | .in(CrmCustomerDO::getOwnerUserId, ownerUserIds) | 192 | .in(CrmCustomerDO::getOwnerUserId, ownerUserIds) |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java
| @@ -199,11 +199,12 @@ public interface CrmBusinessService { | @@ -199,11 +199,12 @@ public interface CrmBusinessService { | ||
| 199 | * | 199 | * |
| 200 | * @param ownerUserIds 负责人编号 | 200 | * @param ownerUserIds 负责人编号 |
| 201 | * @param times 时间范围 | 201 | * @param times 时间范围 |
| 202 | - * @param endStatus 商机结束状态 | 202 | + * @param endStatus 商机结束状态,允许为空 |
| 203 | * @return 商机数 | 203 | * @return 商机数 |
| 204 | */ | 204 | */ |
| 205 | Long getBusinessCountByOwnerUserIdsAndEndStatus(List<Long> ownerUserIds, LocalDateTime[] times, Integer endStatus); | 205 | Long getBusinessCountByOwnerUserIdsAndEndStatus(List<Long> ownerUserIds, LocalDateTime[] times, Integer endStatus); |
| 206 | 206 | ||
| 207 | + // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 207 | /** | 208 | /** |
| 208 | * 获得商机列表【数据统计】 | 209 | * 获得商机列表【数据统计】 |
| 209 | * | 210 | * |
| @@ -213,6 +214,7 @@ public interface CrmBusinessService { | @@ -213,6 +214,7 @@ public interface CrmBusinessService { | ||
| 213 | */ | 214 | */ |
| 214 | List<CrmBusinessDO> getBusinessListByOwnerUserIdsAndEndStatusNotNull(List<Long> ownerUserIds, LocalDateTime[] times); | 215 | List<CrmBusinessDO> getBusinessListByOwnerUserIdsAndEndStatusNotNull(List<Long> ownerUserIds, LocalDateTime[] times); |
| 215 | 216 | ||
| 217 | + // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 216 | /** | 218 | /** |
| 217 | * 获得商机列表【数据统计】 | 219 | * 获得商机列表【数据统计】 |
| 218 | * | 220 | * |
| @@ -223,10 +225,11 @@ public interface CrmBusinessService { | @@ -223,10 +225,11 @@ public interface CrmBusinessService { | ||
| 223 | List<CrmBusinessDO> getBusinessListByOwnerUserIdsAndDate(List<Long> ownerUserIds, LocalDateTime[] times); | 225 | List<CrmBusinessDO> getBusinessListByOwnerUserIdsAndDate(List<Long> ownerUserIds, LocalDateTime[] times); |
| 224 | 226 | ||
| 225 | /** | 227 | /** |
| 226 | - * 商机分页【数据统计】 | 228 | + * 获得商机分页,目前用于【数据统计】 |
| 229 | + * | ||
| 227 | * @param ownerUserIds 负责人编号 | 230 | * @param ownerUserIds 负责人编号 |
| 228 | * @param times 时间范围 | 231 | * @param times 时间范围 |
| 229 | - * @param pageNo 页码 | 232 | + * @param pageNo 页码 TODO @puhui999:直接传递 CrmStatisticsFunnelReqVO 吧,虽然有点耦合,但是更清晰一点; |
| 230 | * @param pageSize 数量 | 233 | * @param pageSize 数量 |
| 231 | * @return 商机分页 | 234 | * @return 商机分页 |
| 232 | */ | 235 | */ |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
| @@ -383,6 +383,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | @@ -383,6 +383,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | ||
| 383 | return businessMapper.selectCountByOwnerUserIdsAndEndStatus(convertSet(ownerUserIds), times, endStatus); | 383 | return businessMapper.selectCountByOwnerUserIdsAndEndStatus(convertSet(ownerUserIds), times, endStatus); |
| 384 | } | 384 | } |
| 385 | 385 | ||
| 386 | + // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 386 | @Override | 387 | @Override |
| 387 | public List<CrmBusinessDO> getBusinessListByOwnerUserIdsAndEndStatusNotNull(List<Long> ownerUserIds, LocalDateTime[] times) { | 388 | public List<CrmBusinessDO> getBusinessListByOwnerUserIdsAndEndStatusNotNull(List<Long> ownerUserIds, LocalDateTime[] times) { |
| 388 | if (CollUtil.isEmpty(ownerUserIds)) { | 389 | if (CollUtil.isEmpty(ownerUserIds)) { |
| @@ -391,6 +392,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | @@ -391,6 +392,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | ||
| 391 | return businessMapper.selectListByOwnerUserIdsAndEndStatusNotNull(convertSet(ownerUserIds), times); | 392 | return businessMapper.selectListByOwnerUserIdsAndEndStatusNotNull(convertSet(ownerUserIds), times); |
| 392 | } | 393 | } |
| 393 | 394 | ||
| 395 | + // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 394 | @Override | 396 | @Override |
| 395 | public List<CrmBusinessDO> getBusinessListByOwnerUserIdsAndDate(List<Long> ownerUserIds, LocalDateTime[] times) { | 397 | public List<CrmBusinessDO> getBusinessListByOwnerUserIdsAndDate(List<Long> ownerUserIds, LocalDateTime[] times) { |
| 396 | if (CollUtil.isEmpty(ownerUserIds)) { | 398 | if (CollUtil.isEmpty(ownerUserIds)) { |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsFunnelServiceImpl.java
| @@ -51,6 +51,7 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | @@ -51,6 +51,7 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | ||
| 51 | @Resource | 51 | @Resource |
| 52 | private DeptApi deptApi; | 52 | private DeptApi deptApi; |
| 53 | 53 | ||
| 54 | + // TODO @puhui999:貌似想了下,可能还是得按照;;; | ||
| 54 | @Override | 55 | @Override |
| 55 | public CrmStatisticFunnelRespVO getFunnelSummary(CrmStatisticsFunnelReqVO reqVO) { | 56 | public CrmStatisticFunnelRespVO getFunnelSummary(CrmStatisticsFunnelReqVO reqVO) { |
| 56 | // 1. 获得用户编号数组 | 57 | // 1. 获得用户编号数组 |
| @@ -76,6 +77,7 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | @@ -76,6 +77,7 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | ||
| 76 | return Collections.emptyList(); | 77 | return Collections.emptyList(); |
| 77 | } | 78 | } |
| 78 | 79 | ||
| 80 | + // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 79 | // 2.1 获得用户负责的商机 | 81 | // 2.1 获得用户负责的商机 |
| 80 | List<CrmBusinessDO> businessList = businessService.getBusinessListByOwnerUserIdsAndEndStatusNotNull(reqVO.getUserIds(), reqVO.getTimes()); | 82 | List<CrmBusinessDO> businessList = businessService.getBusinessListByOwnerUserIdsAndEndStatusNotNull(reqVO.getUserIds(), reqVO.getTimes()); |
| 81 | // 2.2 统计各阶段数据 | 83 | // 2.2 统计各阶段数据 |
| @@ -99,6 +101,7 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | @@ -99,6 +101,7 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | ||
| 99 | } | 101 | } |
| 100 | 102 | ||
| 101 | // 2. 按天统计,获取分项统计数据 | 103 | // 2. 按天统计,获取分项统计数据 |
| 104 | + // TODO @puhui999:可以这个统计,返回的时候,就把数量、金额一起统计好; | ||
| 102 | List<CrmStatisticsBusinessSummaryByDateRespVO> businessCreateCountList = funnelMapper.selectBusinessCreateCountGroupByDate(reqVO); | 105 | List<CrmStatisticsBusinessSummaryByDateRespVO> businessCreateCountList = funnelMapper.selectBusinessCreateCountGroupByDate(reqVO); |
| 103 | List<CrmBusinessDO> businessList = businessService.getBusinessListByOwnerUserIdsAndDate(reqVO.getUserIds(), reqVO.getTimes()); | 106 | List<CrmBusinessDO> businessList = businessService.getBusinessListByOwnerUserIdsAndDate(reqVO.getUserIds(), reqVO.getTimes()); |
| 104 | Map<String, BigDecimal> businessDealCountMap = businessList.stream().collect(Collectors.groupingBy(business -> | 107 | Map<String, BigDecimal> businessDealCountMap = businessList.stream().collect(Collectors.groupingBy(business -> |
| @@ -128,7 +131,7 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | @@ -128,7 +131,7 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | ||
| 128 | if (CollUtil.isEmpty(pageVO.getUserIds())) { | 131 | if (CollUtil.isEmpty(pageVO.getUserIds())) { |
| 129 | return PageResult.empty(); | 132 | return PageResult.empty(); |
| 130 | } | 133 | } |
| 131 | - | 134 | + // 2. 执行查询 |
| 132 | return businessService.getBusinessPageByDate(pageVO.getUserIds(), pageVO.getTimes(), pageVO.getPageNo(), pageVO.getPageSize()); | 135 | return businessService.getBusinessPageByDate(pageVO.getUserIds(), pageVO.getTimes(), pageVO.getPageNo(), pageVO.getPageSize()); |
| 133 | } | 136 | } |
| 134 | 137 |
yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsFunnelMapper.xml
| @@ -4,15 +4,16 @@ | @@ -4,15 +4,16 @@ | ||
| 4 | 4 | ||
| 5 | <select id="selectBusinessCreateCountGroupByDate" | 5 | <select id="selectBusinessCreateCountGroupByDate" |
| 6 | resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO"> | 6 | resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO"> |
| 7 | - SELECT DATE_FORMAT(create_time, '%Y-%m-%d') AS time, COUNT(*) AS businessCreateCount | 7 | + SELECT |
| 8 | + DATE_FORMAT(create_time, '%Y-%m-%d') AS time, | ||
| 9 | + COUNT(*) AS businessCreateCount | ||
| 8 | FROM crm_business | 10 | FROM crm_business |
| 9 | WHERE deleted = 0 | 11 | WHERE deleted = 0 |
| 10 | AND owner_user_id IN | 12 | AND owner_user_id IN |
| 11 | - <foreach collection="userIds" item="userId" open="(" close=")" separator=","> | ||
| 12 | - #{userId} | ||
| 13 | - </foreach> | ||
| 14 | - AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND | ||
| 15 | - #{times[1],javaType=java.time.LocalDateTime} | 13 | + <foreach collection="userIds" item="userId" open="(" close=")" separator=","> |
| 14 | + #{userId} | ||
| 15 | + </foreach> | ||
| 16 | + AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND #{times[1],javaType=java.time.LocalDateTime} | ||
| 16 | GROUP BY time | 17 | GROUP BY time |
| 17 | </select> | 18 | </select> |
| 18 | 19 |