Commit 5cf34c2ba74248ab9e5070525de8e7d06f8f111f
1 parent
ed5f3a6b
CRM: 完善销售漏斗
Showing
17 changed files
with
110 additions
and
314 deletions
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsFunnelController.java
| @@ -5,8 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | @@ -5,8 +5,8 @@ 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.module.crm.controller.admin.business.CrmBusinessController; | 6 | import cn.iocoder.yudao.module.crm.controller.admin.business.CrmBusinessController; |
| 7 | 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; |
| 8 | -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticBusinessEndStatusRespVO; | ||
| 9 | -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticFunnelRespVO; | 8 | +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByEndStatusRespVO; |
| 9 | +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticFunnelSummaryRespVO; | ||
| 10 | 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; |
| 11 | 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; |
| 12 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; | 12 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; |
| @@ -31,37 +31,35 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | @@ -31,37 +31,35 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 31 | @Validated | 31 | @Validated |
| 32 | public class CrmStatisticsFunnelController { | 32 | public class CrmStatisticsFunnelController { |
| 33 | 33 | ||
| 34 | - // TODO @puhui999:crmStatisticsFunnelService 改成 funnelService 更好点哈 | ||
| 35 | @Resource | 34 | @Resource |
| 36 | - private CrmStatisticsFunnelService crmStatisticsFunnelService; | 35 | + private CrmStatisticsFunnelService funnelService; |
| 37 | 36 | ||
| 38 | @GetMapping("/get-funnel-summary") | 37 | @GetMapping("/get-funnel-summary") |
| 39 | @Operation(summary = "获取销售漏斗统计数据", description = "用于【销售漏斗】页面的【销售漏斗分析】") | 38 | @Operation(summary = "获取销售漏斗统计数据", description = "用于【销售漏斗】页面的【销售漏斗分析】") |
| 40 | @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')") | 39 | @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')") |
| 41 | - public CommonResult<CrmStatisticFunnelRespVO> getFunnelSummary(@Valid CrmStatisticsFunnelReqVO reqVO) { | ||
| 42 | - return success(crmStatisticsFunnelService.getFunnelSummary(reqVO)); | 40 | + public CommonResult<CrmStatisticFunnelSummaryRespVO> getFunnelSummary(@Valid CrmStatisticsFunnelReqVO reqVO) { |
| 41 | + return success(funnelService.getFunnelSummary(reqVO)); | ||
| 43 | } | 42 | } |
| 44 | 43 | ||
| 45 | - // TODO @puhui:这个接口,应该是 getBusinessSummaryByEndStatus?这样更统一哈; | ||
| 46 | - @GetMapping("/get-business-end-status-summary") | 44 | + @GetMapping("/get-business-summary-by-end-status") |
| 47 | @Operation(summary = "获取商机结束状态统计", description = "用于【销售漏斗】页面的【销售漏斗分析】") | 45 | @Operation(summary = "获取商机结束状态统计", description = "用于【销售漏斗】页面的【销售漏斗分析】") |
| 48 | @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')") | 46 | @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')") |
| 49 | - public CommonResult<List<CrmStatisticBusinessEndStatusRespVO>> getBusinessEndStatusSummary(@Valid CrmStatisticsFunnelReqVO reqVO) { | ||
| 50 | - return success(crmStatisticsFunnelService.getBusinessEndStatusSummary(reqVO)); | 47 | + public CommonResult<List<CrmStatisticsBusinessSummaryByEndStatusRespVO>> getBusinessSummaryByEndStatus(@Valid CrmStatisticsFunnelReqVO reqVO) { |
| 48 | + return success(funnelService.getBusinessSummaryByEndStatus(reqVO)); | ||
| 51 | } | 49 | } |
| 52 | 50 | ||
| 53 | @GetMapping("/get-business-summary-by-date") | 51 | @GetMapping("/get-business-summary-by-date") |
| 54 | @Operation(summary = "获取新增商机分析(按日期)", description = "用于【销售漏斗】页面") | 52 | @Operation(summary = "获取新增商机分析(按日期)", description = "用于【销售漏斗】页面") |
| 55 | @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')") | 53 | @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')") |
| 56 | public CommonResult<List<CrmStatisticsBusinessSummaryByDateRespVO>> getBusinessSummaryByDate(@Valid CrmStatisticsFunnelReqVO reqVO) { | 54 | public CommonResult<List<CrmStatisticsBusinessSummaryByDateRespVO>> getBusinessSummaryByDate(@Valid CrmStatisticsFunnelReqVO reqVO) { |
| 57 | - return success(crmStatisticsFunnelService.getBusinessSummaryByDate(reqVO)); | 55 | + return success(funnelService.getBusinessSummaryByDate(reqVO)); |
| 58 | } | 56 | } |
| 59 | 57 | ||
| 60 | @GetMapping("/get-business-page-by-date") | 58 | @GetMapping("/get-business-page-by-date") |
| 61 | @Operation(summary = "获得商机分页(按日期)", description = "用于【销售漏斗】页面的【新增商机分析】") | 59 | @Operation(summary = "获得商机分页(按日期)", description = "用于【销售漏斗】页面的【新增商机分析】") |
| 62 | @PreAuthorize("@ss.hasPermission('crm:business:query')") | 60 | @PreAuthorize("@ss.hasPermission('crm:business:query')") |
| 63 | public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByDate(@Valid CrmStatisticsFunnelReqVO pageVO) { | 61 | public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByDate(@Valid CrmStatisticsFunnelReqVO pageVO) { |
| 64 | - PageResult<CrmBusinessDO> pageResult = crmStatisticsFunnelService.getBusinessPageByDate(pageVO); | 62 | + PageResult<CrmBusinessDO> pageResult = funnelService.getBusinessPageByDate(pageVO); |
| 65 | return success(new PageResult<>(buildBusinessDetailList(pageResult.getList()), pageResult.getTotal())); | 63 | return success(new PageResult<>(buildBusinessDetailList(pageResult.getList()), pageResult.getTotal())); |
| 66 | } | 64 | } |
| 67 | 65 |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticFunnelRespVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticFunnelSummaryRespVO.java
| @@ -5,12 +5,11 @@ import lombok.AllArgsConstructor; | @@ -5,12 +5,11 @@ 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 更有统计的味道 | ||
| 9 | @Schema(description = "管理后台 - CRM 销售漏斗 Response VO") | 8 | @Schema(description = "管理后台 - CRM 销售漏斗 Response VO") |
| 10 | @NoArgsConstructor | 9 | @NoArgsConstructor |
| 11 | @AllArgsConstructor | 10 | @AllArgsConstructor |
| 12 | @Data | 11 | @Data |
| 13 | -public class CrmStatisticFunnelRespVO { | 12 | +public class CrmStatisticFunnelSummaryRespVO { |
| 14 | 13 | ||
| 15 | @Schema(description = "客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 14 | @Schema(description = "客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 16 | private Long customerCount; | 15 | private Long customerCount; |
| @@ -18,8 +17,7 @@ public class CrmStatisticFunnelRespVO { | @@ -18,8 +17,7 @@ public class CrmStatisticFunnelRespVO { | ||
| 18 | @Schema(description = "商机数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 17 | @Schema(description = "商机数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 19 | private Long businessCount; | 18 | private Long businessCount; |
| 20 | 19 | ||
| 21 | - // TODO @puhui999:这个改成 businessWinCount 可能会更合适点哈; | ||
| 22 | @Schema(description = "赢单数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 20 | @Schema(description = "赢单数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 23 | - private Long winCount; | 21 | + private Long businessWinCount; |
| 24 | 22 | ||
| 25 | } | 23 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticsBusinessRespVO.java deleted
| 1 | -package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel; | ||
| 2 | - | ||
| 3 | -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; | ||
| 4 | -import com.alibaba.excel.annotation.ExcelProperty; | ||
| 5 | -import io.swagger.v3.oas.annotations.media.Schema; | ||
| 6 | -import lombok.Data; | ||
| 7 | - | ||
| 8 | -import java.math.BigDecimal; | ||
| 9 | -import java.time.LocalDateTime; | ||
| 10 | - | ||
| 11 | -// TODO @puhui999:是不是可以删除哈? | ||
| 12 | -@Schema(description = "管理后台 - CRM 商机 Response VO") | ||
| 13 | -@Data | ||
| 14 | -@ExcelIgnoreUnannotated | ||
| 15 | -public class CrmStatisticsBusinessRespVO { | ||
| 16 | - | ||
| 17 | - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129") | ||
| 18 | - @ExcelProperty("编号") | ||
| 19 | - private Long id; | ||
| 20 | - | ||
| 21 | - @Schema(description = "商机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") | ||
| 22 | - @ExcelProperty("商机名称") | ||
| 23 | - private String name; | ||
| 24 | - | ||
| 25 | - @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10299") | ||
| 26 | - private Long customerId; | ||
| 27 | - @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") | ||
| 28 | - @ExcelProperty("客户名称") | ||
| 29 | - private String customerName; | ||
| 30 | - | ||
| 31 | - @Schema(description = "跟进状态", requiredMode = Schema.RequiredMode.REQUIRED, example ="true") | ||
| 32 | - @ExcelProperty("跟进状态") | ||
| 33 | - private Boolean followUpStatus; | ||
| 34 | - | ||
| 35 | - @Schema(description = "最后跟进时间") | ||
| 36 | - @ExcelProperty("最后跟进时间") | ||
| 37 | - private LocalDateTime contactLastTime; | ||
| 38 | - | ||
| 39 | - @Schema(description = "下次联系时间") | ||
| 40 | - @ExcelProperty("下次联系时间") | ||
| 41 | - private LocalDateTime contactNextTime; | ||
| 42 | - | ||
| 43 | - @Schema(description = "负责人的用户编号", example = "25682") | ||
| 44 | - @ExcelProperty("负责人的用户编号") | ||
| 45 | - private Long ownerUserId; | ||
| 46 | - @Schema(description = "负责人名字", example = "25682") | ||
| 47 | - @ExcelProperty("负责人名字") | ||
| 48 | - private String ownerUserName; | ||
| 49 | - @Schema(description = "负责人部门") | ||
| 50 | - @ExcelProperty("负责人部门") | ||
| 51 | - private String ownerUserDeptName; | ||
| 52 | - | ||
| 53 | - @Schema(description = "商机状态组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714") | ||
| 54 | - private Long statusTypeId; | ||
| 55 | - @Schema(description = "商机状组名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "进行中") | ||
| 56 | - @ExcelProperty("商机状态组") | ||
| 57 | - private String statusTypeName; | ||
| 58 | - | ||
| 59 | - @Schema(description = "商机状态编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") | ||
| 60 | - private Long statusId; | ||
| 61 | - @Schema(description = "状态名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "跟进中") | ||
| 62 | - @ExcelProperty("商机状态") | ||
| 63 | - private String statusName; | ||
| 64 | - | ||
| 65 | - @Schema | ||
| 66 | - @ExcelProperty("结束状态") | ||
| 67 | - private Integer endStatus; | ||
| 68 | - | ||
| 69 | - @ExcelProperty("结束时的备注") | ||
| 70 | - private String endRemark; | ||
| 71 | - | ||
| 72 | - @Schema(description = "预计成交日期") | ||
| 73 | - @ExcelProperty("预计成交日期") | ||
| 74 | - private LocalDateTime dealTime; | ||
| 75 | - | ||
| 76 | - @Schema(description = "产品总金额", example = "12025") | ||
| 77 | - @ExcelProperty("产品总金额") | ||
| 78 | - private BigDecimal totalProductPrice; | ||
| 79 | - | ||
| 80 | - @Schema(description = "整单折扣") | ||
| 81 | - @ExcelProperty("整单折扣") | ||
| 82 | - private BigDecimal discountPercent; | ||
| 83 | - | ||
| 84 | - @Schema(description = "商机总金额", example = "12371") | ||
| 85 | - @ExcelProperty("商机总金额") | ||
| 86 | - private BigDecimal totalPrice; | ||
| 87 | - | ||
| 88 | - @Schema(description = "备注", example = "随便") | ||
| 89 | - @ExcelProperty("备注") | ||
| 90 | - private String remark; | ||
| 91 | - | ||
| 92 | - @Schema(description = "创建人", example = "1024") | ||
| 93 | - @ExcelProperty("创建人") | ||
| 94 | - private String creator; | ||
| 95 | - @Schema(description = "创建人名字", example = "芋道源码") | ||
| 96 | - @ExcelProperty("创建人名字") | ||
| 97 | - private String creatorName; | ||
| 98 | - | ||
| 99 | - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 100 | - @ExcelProperty("创建时间") | ||
| 101 | - private LocalDateTime createTime; | ||
| 102 | - | ||
| 103 | - @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 104 | - @ExcelProperty("更新时间") | ||
| 105 | - private LocalDateTime updateTime; | ||
| 106 | - | ||
| 107 | -} |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticsBusinessSummaryByDateRespVO.java
| @@ -15,8 +15,7 @@ public class CrmStatisticsBusinessSummaryByDateRespVO { | @@ -15,8 +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:是不是金额哈,不是数量 | ||
| 19 | @Schema(description = "新增商机金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 18 | @Schema(description = "新增商机金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 20 | - private BigDecimal businessDealCount; | 19 | + private BigDecimal totalPrice; |
| 21 | 20 | ||
| 22 | } | 21 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticBusinessEndStatusRespVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticsBusinessSummaryByEndStatusRespVO.java
| @@ -7,12 +7,11 @@ import lombok.NoArgsConstructor; | @@ -7,12 +7,11 @@ import lombok.NoArgsConstructor; | ||
| 7 | 7 | ||
| 8 | import java.math.BigDecimal; | 8 | import java.math.BigDecimal; |
| 9 | 9 | ||
| 10 | -// TODO @puhui999:改成 CrmStatisticsBusinessSummaryByEndStatusRespVO,按照结束状态 | ||
| 11 | @Schema(description = "管理后台 - CRM 商机结束状态统计 Response VO") | 10 | @Schema(description = "管理后台 - CRM 商机结束状态统计 Response VO") |
| 12 | @NoArgsConstructor | 11 | @NoArgsConstructor |
| 13 | @AllArgsConstructor | 12 | @AllArgsConstructor |
| 14 | @Data | 13 | @Data |
| 15 | -public class CrmStatisticBusinessEndStatusRespVO { | 14 | +public class CrmStatisticsBusinessSummaryByEndStatusRespVO { |
| 16 | 15 | ||
| 17 | @Schema(description = "结束状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 16 | @Schema(description = "结束状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 18 | private Integer endStatus; | 17 | private Integer endStatus; |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticsFunnelReqVO.java
| @@ -5,9 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; | @@ -5,9 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 5 | import cn.iocoder.yudao.framework.common.validation.InEnum; | 5 | import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 6 | import io.swagger.v3.oas.annotations.media.Schema; | 6 | import io.swagger.v3.oas.annotations.media.Schema; |
| 7 | import jakarta.validation.constraints.NotNull; | 7 | import jakarta.validation.constraints.NotNull; |
| 8 | +import jakarta.validation.constraints.Size; | ||
| 8 | import lombok.Data; | 9 | import lombok.Data; |
| 9 | -import lombok.EqualsAndHashCode; | ||
| 10 | -import lombok.ToString; | ||
| 11 | import org.springframework.format.annotation.DateTimeFormat; | 10 | import org.springframework.format.annotation.DateTimeFormat; |
| 12 | 11 | ||
| 13 | import java.time.LocalDateTime; | 12 | import java.time.LocalDateTime; |
| @@ -17,9 +16,6 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ | @@ -17,9 +16,6 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ | ||
| 17 | 16 | ||
| 18 | @Schema(description = "管理后台 - CRM 销售漏斗 Request VO") | 17 | @Schema(description = "管理后台 - CRM 销售漏斗 Request VO") |
| 19 | @Data | 18 | @Data |
| 20 | -// TODO @puhui999:不用写 EqualsAndHashCode、ToString,已经全局 lombok 啦 | ||
| 21 | -@EqualsAndHashCode(callSuper = true) | ||
| 22 | -@ToString(callSuper = true) | ||
| 23 | public class CrmStatisticsFunnelReqVO extends PageParam { | 19 | public class CrmStatisticsFunnelReqVO extends PageParam { |
| 24 | 20 | ||
| 25 | @Schema(description = "部门 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 21 | @Schema(description = "部门 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| @@ -43,13 +39,9 @@ public class CrmStatisticsFunnelReqVO extends PageParam { | @@ -43,13 +39,9 @@ public class CrmStatisticsFunnelReqVO extends PageParam { | ||
| 43 | @InEnum(value = DateIntervalEnum.class, message = "时间间隔类型,必须是 {value}") | 39 | @InEnum(value = DateIntervalEnum.class, message = "时间间隔类型,必须是 {value}") |
| 44 | private Integer interval; | 40 | private Integer interval; |
| 45 | 41 | ||
| 46 | - // TODO @puhui999:这个全部前端传递哈;参考 CrmStatisticsCustomerReqVO | ||
| 47 | - /** | ||
| 48 | - * 前端如果选择自定义时间, 那么前端传递起始-终止时间, 如果选择其他时间间隔类型, 则由后台计算起始-终止时间 | ||
| 49 | - * 并作为参数传递给Mapper | ||
| 50 | - */ | ||
| 51 | @Schema(description = "时间范围", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 42 | @Schema(description = "时间范围", requiredMode = Schema.RequiredMode.NOT_REQUIRED) |
| 52 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | 43 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 44 | + @Size(min = 2, max = 2, message = "请选择时间范围") | ||
| 53 | private LocalDateTime[] times; | 45 | private LocalDateTime[] times; |
| 54 | 46 | ||
| 55 | } | 47 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticsPortraitReqVO.java
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait; | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait; | ||
| 2 | 2 | ||
| 3 | import io.swagger.v3.oas.annotations.media.Schema; | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | import jakarta.validation.constraints.NotNull; | 4 | import jakarta.validation.constraints.NotNull; |
| 5 | +import jakarta.validation.constraints.Size; | ||
| 5 | import lombok.Data; | 6 | import lombok.Data; |
| 6 | import org.springframework.format.annotation.DateTimeFormat; | 7 | import org.springframework.format.annotation.DateTimeFormat; |
| 7 | 8 | ||
| @@ -31,12 +32,9 @@ public class CrmStatisticsPortraitReqVO { | @@ -31,12 +32,9 @@ public class CrmStatisticsPortraitReqVO { | ||
| 31 | @Schema(description = "负责人用户 id 集合", hidden = true, example = "2") | 32 | @Schema(description = "负责人用户 id 集合", hidden = true, example = "2") |
| 32 | private List<Long> userIds; | 33 | private List<Long> userIds; |
| 33 | 34 | ||
| 34 | - /** | ||
| 35 | - * 前端如果选择自定义时间, 那么前端传递起始-终止时间, 如果选择其他时间间隔类型, 则由后台计算起始-终止时间 | ||
| 36 | - * 并作为参数传递给Mapper | ||
| 37 | - */ | ||
| 38 | @Schema(description = "时间范围", requiredMode = Schema.RequiredMode.NOT_REQUIRED) | 35 | @Schema(description = "时间范围", requiredMode = Schema.RequiredMode.NOT_REQUIRED) |
| 39 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | 36 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 37 | + @Size(min = 2, max = 2, message = "请选择时间范围") | ||
| 40 | private LocalDateTime[] times; | 38 | private LocalDateTime[] times; |
| 41 | 39 | ||
| 42 | } | 40 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java
| 1 | package cn.iocoder.yudao.module.crm.dal.mysql.business; | 1 | package cn.iocoder.yudao.module.crm.dal.mysql.business; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 6 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 7 | import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; |
| 8 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; | 7 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; |
| 8 | +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; | ||
| 9 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; | 9 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; |
| 10 | import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; | 10 | import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; |
| 11 | import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils; | 11 | import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils; |
| 12 | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | 12 | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| 13 | import org.apache.ibatis.annotations.Mapper; | 13 | import org.apache.ibatis.annotations.Mapper; |
| 14 | 14 | ||
| 15 | -import java.time.LocalDateTime; | ||
| 16 | import java.util.Collection; | 15 | import java.util.Collection; |
| 17 | import java.util.List; | 16 | import java.util.List; |
| 18 | 17 | ||
| @@ -66,32 +65,10 @@ public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> { | @@ -66,32 +65,10 @@ public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> { | ||
| 66 | .eq(CrmBusinessDO::getOwnerUserId, ownerUserId)); | 65 | .eq(CrmBusinessDO::getOwnerUserId, ownerUserId)); |
| 67 | } | 66 | } |
| 68 | 67 | ||
| 69 | - default Long selectCountByOwnerUserIdsAndEndStatus(Collection<Long> ownerUserIds, LocalDateTime[] times, Integer endStatus) { | ||
| 70 | - return selectCount(new LambdaQueryWrapperX<CrmBusinessDO>() | ||
| 71 | - .in(CrmBusinessDO::getOwnerUserId, ownerUserIds) | ||
| 72 | - .eqIfPresent(CrmBusinessDO::getEndStatus, endStatus) | ||
| 73 | - .betweenIfPresent(CrmBusinessDO::getCreateTime, times)); | ||
| 74 | - } | ||
| 75 | - | ||
| 76 | - // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 77 | - default List<CrmBusinessDO> selectListByOwnerUserIdsAndEndStatusNotNull(Collection<Long> ownerUserIds, LocalDateTime[] times) { | ||
| 78 | - return selectList(new LambdaQueryWrapperX<CrmBusinessDO>() | ||
| 79 | - .in(CrmBusinessDO::getOwnerUserId, ownerUserIds) | ||
| 80 | - .betweenIfPresent(CrmBusinessDO::getCreateTime, times) | ||
| 81 | - .isNotNull(CrmBusinessDO::getEndStatus)); | ||
| 82 | - } | ||
| 83 | - | ||
| 84 | - // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 85 | - default List<CrmBusinessDO> selectListByOwnerUserIdsAndDate(Collection<Long> ownerUserIds, LocalDateTime[] times) { | ||
| 86 | - return selectList(new LambdaQueryWrapperX<CrmBusinessDO>() | ||
| 87 | - .in(CrmBusinessDO::getOwnerUserId, ownerUserIds) | ||
| 88 | - .betweenIfPresent(CrmBusinessDO::getCreateTime, times)); | ||
| 89 | - } | ||
| 90 | - | ||
| 91 | - default PageResult<CrmBusinessDO> selectPage(Collection<Long> ownerUserIds, LocalDateTime[] times, Integer pageNo, Integer pageSize) { | ||
| 92 | - return selectPage(new PageParam().setPageNo(pageNo).setPageSize(pageSize), new LambdaQueryWrapperX<CrmBusinessDO>() | ||
| 93 | - .in(CrmBusinessDO::getOwnerUserId, ownerUserIds) | ||
| 94 | - .betweenIfPresent(CrmBusinessDO::getCreateTime, times)); | 68 | + default PageResult<CrmBusinessDO> selectPage(CrmStatisticsFunnelReqVO pageVO) { |
| 69 | + return selectPage(pageVO, new LambdaQueryWrapperX<CrmBusinessDO>() | ||
| 70 | + .in(CrmBusinessDO::getOwnerUserId, pageVO.getUserIds()) | ||
| 71 | + .betweenIfPresent(CrmBusinessDO::getCreateTime, pageVO.getTimes())); | ||
| 95 | } | 72 | } |
| 96 | 73 | ||
| 97 | } | 74 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java
| @@ -186,11 +186,4 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> { | @@ -186,11 +186,4 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> { | ||
| 186 | return selectCount(query); | 186 | return selectCount(query); |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | - // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 190 | - default Long selectCountByOwnerUserIds(Collection<Long> ownerUserIds, LocalDateTime[] times){ | ||
| 191 | - return selectCount(new LambdaQueryWrapperX<CrmCustomerDO>() | ||
| 192 | - .in(CrmCustomerDO::getOwnerUserId, ownerUserIds) | ||
| 193 | - .betweenIfPresent(CrmCustomerDO::getCreateTime, times)); | ||
| 194 | - } | ||
| 195 | - | ||
| 196 | } | 189 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsFunnelMapper.java
| 1 | package cn.iocoder.yudao.module.crm.dal.mysql.statistics; | 1 | package cn.iocoder.yudao.module.crm.dal.mysql.statistics; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerSummaryByDateRespVO; | ||
| 4 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO; | 3 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO; |
| 4 | +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByEndStatusRespVO; | ||
| 5 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; | 5 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; |
| 6 | import org.apache.ibatis.annotations.Mapper; | 6 | import org.apache.ibatis.annotations.Mapper; |
| 7 | +import org.apache.ibatis.annotations.Param; | ||
| 7 | 8 | ||
| 8 | import java.util.List; | 9 | import java.util.List; |
| 9 | 10 | ||
| @@ -15,6 +16,12 @@ import java.util.List; | @@ -15,6 +16,12 @@ import java.util.List; | ||
| 15 | @Mapper | 16 | @Mapper |
| 16 | public interface CrmStatisticsFunnelMapper { | 17 | public interface CrmStatisticsFunnelMapper { |
| 17 | 18 | ||
| 18 | - List<CrmStatisticsBusinessSummaryByDateRespVO> selectBusinessCreateCountGroupByDate(CrmStatisticsFunnelReqVO reqVO); | 19 | + Long selectCustomerCountByDate(CrmStatisticsFunnelReqVO reqVO); |
| 20 | + | ||
| 21 | + Long selectBusinessCountByDateAndEndStatus(@Param("reqVO") CrmStatisticsFunnelReqVO reqVO, @Param("status") Integer status); | ||
| 22 | + | ||
| 23 | + List<CrmStatisticsBusinessSummaryByEndStatusRespVO> selectBusinessSummaryListGroupByEndStatus(CrmStatisticsFunnelReqVO reqVO); | ||
| 24 | + | ||
| 25 | + List<CrmStatisticsBusinessSummaryByDateRespVO> selectBusinessSummaryGroupByDate(CrmStatisticsFunnelReqVO reqVO); | ||
| 19 | 26 | ||
| 20 | } | 27 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java
| @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi | @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi | ||
| 5 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO; | 5 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO; |
| 6 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; | 6 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; |
| 7 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateStatusReqVO; | 7 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateStatusReqVO; |
| 8 | +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; | ||
| 8 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; | 9 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; |
| 9 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; | 10 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; |
| 10 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; | 11 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; |
| @@ -195,44 +196,11 @@ public interface CrmBusinessService { | @@ -195,44 +196,11 @@ public interface CrmBusinessService { | ||
| 195 | List<CrmBusinessDO> getBusinessListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId); | 196 | List<CrmBusinessDO> getBusinessListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId); |
| 196 | 197 | ||
| 197 | /** | 198 | /** |
| 198 | - * 获得商机数 | ||
| 199 | - * | ||
| 200 | - * @param ownerUserIds 负责人编号 | ||
| 201 | - * @param times 时间范围 | ||
| 202 | - * @param endStatus 商机结束状态,允许为空 | ||
| 203 | - * @return 商机数 | ||
| 204 | - */ | ||
| 205 | - Long getBusinessCountByOwnerUserIdsAndEndStatus(List<Long> ownerUserIds, LocalDateTime[] times, Integer endStatus); | ||
| 206 | - | ||
| 207 | - // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 208 | - /** | ||
| 209 | - * 获得商机列表【数据统计】 | ||
| 210 | - * | ||
| 211 | - * @param ownerUserIds 负责人编号 | ||
| 212 | - * @param times 时间范围 | ||
| 213 | - * @return 商机列表 | ||
| 214 | - */ | ||
| 215 | - List<CrmBusinessDO> getBusinessListByOwnerUserIdsAndEndStatusNotNull(List<Long> ownerUserIds, LocalDateTime[] times); | ||
| 216 | - | ||
| 217 | - // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 218 | - /** | ||
| 219 | - * 获得商机列表【数据统计】 | ||
| 220 | - * | ||
| 221 | - * @param ownerUserIds 负责人编号 | ||
| 222 | - * @param times 时间范围 | ||
| 223 | - * @return 商机列表 | ||
| 224 | - */ | ||
| 225 | - List<CrmBusinessDO> getBusinessListByOwnerUserIdsAndDate(List<Long> ownerUserIds, LocalDateTime[] times); | ||
| 226 | - | ||
| 227 | - /** | ||
| 228 | * 获得商机分页,目前用于【数据统计】 | 199 | * 获得商机分页,目前用于【数据统计】 |
| 229 | * | 200 | * |
| 230 | - * @param ownerUserIds 负责人编号 | ||
| 231 | - * @param times 时间范围 | ||
| 232 | - * @param pageNo 页码 TODO @puhui999:直接传递 CrmStatisticsFunnelReqVO 吧,虽然有点耦合,但是更清晰一点; | ||
| 233 | - * @param pageSize 数量 | 201 | + * @param pageVO 请求 |
| 234 | * @return 商机分页 | 202 | * @return 商机分页 |
| 235 | */ | 203 | */ |
| 236 | - PageResult<CrmBusinessDO> getBusinessPageByDate(List<Long> ownerUserIds, LocalDateTime[] times, Integer pageNo, Integer pageSize); | 204 | + PageResult<CrmBusinessDO> getBusinessPageByDate(CrmStatisticsFunnelReqVO pageVO); |
| 237 | 205 | ||
| 238 | } | 206 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
| @@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi | @@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi | ||
| 10 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; | 10 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; |
| 11 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateStatusReqVO; | 11 | import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateStatusReqVO; |
| 12 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusinessReqVO; | 12 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusinessReqVO; |
| 13 | +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; | ||
| 13 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; | 14 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; |
| 14 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; | 15 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; |
| 15 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; | 16 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; |
| @@ -376,35 +377,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | @@ -376,35 +377,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | ||
| 376 | } | 377 | } |
| 377 | 378 | ||
| 378 | @Override | 379 | @Override |
| 379 | - public Long getBusinessCountByOwnerUserIdsAndEndStatus(List<Long> ownerUserIds, LocalDateTime[] times, Integer endStatus) { | ||
| 380 | - if (CollUtil.isEmpty(ownerUserIds)) { | ||
| 381 | - return 0L; | ||
| 382 | - } | ||
| 383 | - return businessMapper.selectCountByOwnerUserIdsAndEndStatus(convertSet(ownerUserIds), times, endStatus); | ||
| 384 | - } | ||
| 385 | - | ||
| 386 | - // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 387 | - @Override | ||
| 388 | - public List<CrmBusinessDO> getBusinessListByOwnerUserIdsAndEndStatusNotNull(List<Long> ownerUserIds, LocalDateTime[] times) { | ||
| 389 | - if (CollUtil.isEmpty(ownerUserIds)) { | ||
| 390 | - return Collections.emptyList(); | ||
| 391 | - } | ||
| 392 | - return businessMapper.selectListByOwnerUserIdsAndEndStatusNotNull(convertSet(ownerUserIds), times); | ||
| 393 | - } | ||
| 394 | - | ||
| 395 | - // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 396 | - @Override | ||
| 397 | - public List<CrmBusinessDO> getBusinessListByOwnerUserIdsAndDate(List<Long> ownerUserIds, LocalDateTime[] times) { | ||
| 398 | - if (CollUtil.isEmpty(ownerUserIds)) { | ||
| 399 | - return Collections.emptyList(); | ||
| 400 | - } | ||
| 401 | - | ||
| 402 | - return businessMapper.selectListByOwnerUserIdsAndDate(convertSet(ownerUserIds), times); | ||
| 403 | - } | ||
| 404 | - | ||
| 405 | - @Override | ||
| 406 | - public PageResult<CrmBusinessDO> getBusinessPageByDate(List<Long> ownerUserIds, LocalDateTime[] times, Integer pageNo, Integer pageSize) { | ||
| 407 | - return businessMapper.selectPage(ownerUserIds, times, pageNo, pageSize); | 380 | + public PageResult<CrmBusinessDO> getBusinessPageByDate(CrmStatisticsFunnelReqVO pageVO) { |
| 381 | + return businessMapper.selectPage(pageVO); | ||
| 408 | } | 382 | } |
| 409 | 383 | ||
| 410 | } | 384 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java
| @@ -195,13 +195,4 @@ public interface CrmCustomerService { | @@ -195,13 +195,4 @@ public interface CrmCustomerService { | ||
| 195 | */ | 195 | */ |
| 196 | int autoPutCustomerPool(); | 196 | int autoPutCustomerPool(); |
| 197 | 197 | ||
| 198 | - /** | ||
| 199 | - * 获得客户数 | ||
| 200 | - * | ||
| 201 | - * @param ownerUserIds 负责人编号 | ||
| 202 | - * @param times 时间范围 | ||
| 203 | - * @return 客户数 | ||
| 204 | - */ | ||
| 205 | - Long getCustomerCountByOwnerUserIds(List<Long> ownerUserIds, LocalDateTime[] times); | ||
| 206 | - | ||
| 207 | } | 198 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
| @@ -651,14 +651,6 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -651,14 +651,6 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 651 | } | 651 | } |
| 652 | } | 652 | } |
| 653 | 653 | ||
| 654 | - @Override | ||
| 655 | - public Long getCustomerCountByOwnerUserIds(List<Long> ownerUserIds, LocalDateTime[] times) { | ||
| 656 | - if (CollUtil.isEmpty(ownerUserIds)) { | ||
| 657 | - return 0L; | ||
| 658 | - } | ||
| 659 | - return customerMapper.selectCountByOwnerUserIds(convertSet(ownerUserIds), times); | ||
| 660 | - } | ||
| 661 | - | ||
| 662 | /** | 654 | /** |
| 663 | * 获得自身的代理对象,解决 AOP 生效问题 | 655 | * 获得自身的代理对象,解决 AOP 生效问题 |
| 664 | * | 656 | * |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsFunnelService.java
| 1 | package cn.iocoder.yudao.module.crm.service.statistics; | 1 | package cn.iocoder.yudao.module.crm.service.statistics; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticBusinessEndStatusRespVO; | ||
| 5 | -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticFunnelRespVO; | 4 | +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByEndStatusRespVO; |
| 5 | +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticFunnelSummaryRespVO; | ||
| 6 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO; | 6 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO; |
| 7 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; | 7 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; |
| 8 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; | 8 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; |
| @@ -22,7 +22,7 @@ public interface CrmStatisticsFunnelService { | @@ -22,7 +22,7 @@ public interface CrmStatisticsFunnelService { | ||
| 22 | * @param reqVO 请求 | 22 | * @param reqVO 请求 |
| 23 | * @return 销售漏斗数据 | 23 | * @return 销售漏斗数据 |
| 24 | */ | 24 | */ |
| 25 | - CrmStatisticFunnelRespVO getFunnelSummary(CrmStatisticsFunnelReqVO reqVO); | 25 | + CrmStatisticFunnelSummaryRespVO getFunnelSummary(CrmStatisticsFunnelReqVO reqVO); |
| 26 | 26 | ||
| 27 | /** | 27 | /** |
| 28 | * 获得商机结束状态统计 | 28 | * 获得商机结束状态统计 |
| @@ -30,7 +30,7 @@ public interface CrmStatisticsFunnelService { | @@ -30,7 +30,7 @@ public interface CrmStatisticsFunnelService { | ||
| 30 | * @param reqVO 请求 | 30 | * @param reqVO 请求 |
| 31 | * @return 商机结束状态统计 | 31 | * @return 商机结束状态统计 |
| 32 | */ | 32 | */ |
| 33 | - List<CrmStatisticBusinessEndStatusRespVO> getBusinessEndStatusSummary(CrmStatisticsFunnelReqVO reqVO); | 33 | + List<CrmStatisticsBusinessSummaryByEndStatusRespVO> getBusinessSummaryByEndStatus(CrmStatisticsFunnelReqVO reqVO); |
| 34 | 34 | ||
| 35 | /** | 35 | /** |
| 36 | * 获取新增商机分析(按日期) | 36 | * 获取新增商机分析(按日期) |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsFunnelServiceImpl.java
| @@ -4,15 +4,14 @@ import cn.hutool.core.collection.CollUtil; | @@ -4,15 +4,14 @@ import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.hutool.core.util.ObjUtil; | 4 | import cn.hutool.core.util.ObjUtil; |
| 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.date.LocalDateTimeUtils; | 6 | import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; |
| 7 | -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticBusinessEndStatusRespVO; | ||
| 8 | -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticFunnelRespVO; | 7 | +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticFunnelSummaryRespVO; |
| 9 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO; | 8 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO; |
| 9 | +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByEndStatusRespVO; | ||
| 10 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; | 10 | import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO; |
| 11 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; | 11 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; |
| 12 | import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsFunnelMapper; | 12 | import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsFunnelMapper; |
| 13 | import cn.iocoder.yudao.module.crm.enums.business.CrmBusinessEndStatusEnum; | 13 | import cn.iocoder.yudao.module.crm.enums.business.CrmBusinessEndStatusEnum; |
| 14 | import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; | 14 | import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; |
| 15 | -import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; | ||
| 16 | import cn.iocoder.yudao.module.system.api.dept.DeptApi; | 15 | import cn.iocoder.yudao.module.system.api.dept.DeptApi; |
| 17 | import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; | 16 | import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; |
| 18 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | 17 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| @@ -22,14 +21,10 @@ import org.springframework.stereotype.Service; | @@ -22,14 +21,10 @@ import org.springframework.stereotype.Service; | ||
| 22 | 21 | ||
| 23 | import java.math.BigDecimal; | 22 | import java.math.BigDecimal; |
| 24 | import java.time.LocalDateTime; | 23 | import java.time.LocalDateTime; |
| 25 | -import java.time.format.DateTimeFormatter; | ||
| 26 | import java.util.Collections; | 24 | import java.util.Collections; |
| 27 | import java.util.List; | 25 | import java.util.List; |
| 28 | -import java.util.Map; | ||
| 29 | -import java.util.stream.Collectors; | ||
| 30 | 26 | ||
| 31 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | ||
| 32 | -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; | 27 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; |
| 33 | 28 | ||
| 34 | /** | 29 | /** |
| 35 | * CRM 销售漏斗分析 Service 实现类 | 30 | * CRM 销售漏斗分析 Service 实现类 |
| @@ -45,15 +40,12 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | @@ -45,15 +40,12 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | ||
| 45 | @Resource | 40 | @Resource |
| 46 | private AdminUserApi adminUserApi; | 41 | private AdminUserApi adminUserApi; |
| 47 | @Resource | 42 | @Resource |
| 48 | - private CrmCustomerService customerService; | ||
| 49 | - @Resource | ||
| 50 | private CrmBusinessService businessService; | 43 | private CrmBusinessService businessService; |
| 51 | @Resource | 44 | @Resource |
| 52 | private DeptApi deptApi; | 45 | private DeptApi deptApi; |
| 53 | 46 | ||
| 54 | - // TODO @puhui999:貌似想了下,可能还是得按照;;; | ||
| 55 | @Override | 47 | @Override |
| 56 | - public CrmStatisticFunnelRespVO getFunnelSummary(CrmStatisticsFunnelReqVO reqVO) { | 48 | + public CrmStatisticFunnelSummaryRespVO getFunnelSummary(CrmStatisticsFunnelReqVO reqVO) { |
| 57 | // 1. 获得用户编号数组 | 49 | // 1. 获得用户编号数组 |
| 58 | List<Long> userIds = getUserIds(reqVO); | 50 | List<Long> userIds = getUserIds(reqVO); |
| 59 | if (CollUtil.isEmpty(userIds)) { | 51 | if (CollUtil.isEmpty(userIds)) { |
| @@ -62,34 +54,22 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | @@ -62,34 +54,22 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | ||
| 62 | reqVO.setUserIds(userIds); | 54 | reqVO.setUserIds(userIds); |
| 63 | 55 | ||
| 64 | // 2. 获得漏斗数据 | 56 | // 2. 获得漏斗数据 |
| 65 | - return new CrmStatisticFunnelRespVO( | ||
| 66 | - customerService.getCustomerCountByOwnerUserIds(userIds, reqVO.getTimes()), | ||
| 67 | - businessService.getBusinessCountByOwnerUserIdsAndEndStatus(userIds, reqVO.getTimes(), null), | ||
| 68 | - businessService.getBusinessCountByOwnerUserIdsAndEndStatus(userIds, reqVO.getTimes(), CrmBusinessEndStatusEnum.WIN.getStatus()) | ||
| 69 | - ); | 57 | + Long customerCount = funnelMapper.selectCustomerCountByDate(reqVO); |
| 58 | + Long businessCount = funnelMapper.selectBusinessCountByDateAndEndStatus(reqVO, null); | ||
| 59 | + Long businessWinCount = funnelMapper.selectBusinessCountByDateAndEndStatus(reqVO, CrmBusinessEndStatusEnum.WIN.getStatus()); | ||
| 60 | + return new CrmStatisticFunnelSummaryRespVO(customerCount, businessCount, businessWinCount); | ||
| 70 | } | 61 | } |
| 71 | 62 | ||
| 72 | @Override | 63 | @Override |
| 73 | - public List<CrmStatisticBusinessEndStatusRespVO> getBusinessEndStatusSummary(CrmStatisticsFunnelReqVO reqVO) { | 64 | + public List<CrmStatisticsBusinessSummaryByEndStatusRespVO> getBusinessSummaryByEndStatus(CrmStatisticsFunnelReqVO reqVO) { |
| 74 | // 1. 获得用户编号数组 | 65 | // 1. 获得用户编号数组 |
| 75 | reqVO.setUserIds(getUserIds(reqVO)); | 66 | reqVO.setUserIds(getUserIds(reqVO)); |
| 76 | if (CollUtil.isEmpty(reqVO.getUserIds())) { | 67 | if (CollUtil.isEmpty(reqVO.getUserIds())) { |
| 77 | return Collections.emptyList(); | 68 | return Collections.emptyList(); |
| 78 | } | 69 | } |
| 79 | 70 | ||
| 80 | - // TODO @puhui999:这个可以优化下,通过统计 sql,不通过内存计算; | ||
| 81 | - // 2.1 获得用户负责的商机 | ||
| 82 | - List<CrmBusinessDO> businessList = businessService.getBusinessListByOwnerUserIdsAndEndStatusNotNull(reqVO.getUserIds(), reqVO.getTimes()); | ||
| 83 | - // 2.2 统计各阶段数据 | ||
| 84 | - Map<Integer, List<CrmBusinessDO>> businessMap = convertMultiMap(businessList, CrmBusinessDO::getEndStatus); | ||
| 85 | - return convertList(CrmBusinessEndStatusEnum.values(), endStatusEnum -> { | ||
| 86 | - List<CrmBusinessDO> list = businessMap.get(endStatusEnum.getStatus()); | ||
| 87 | - if (CollUtil.isEmpty(list)) { | ||
| 88 | - return new CrmStatisticBusinessEndStatusRespVO(endStatusEnum.getStatus(), 0L, BigDecimal.ZERO); | ||
| 89 | - } | ||
| 90 | - return new CrmStatisticBusinessEndStatusRespVO(endStatusEnum.getStatus(), (long) list.size(), | ||
| 91 | - getSumValue(list, CrmBusinessDO::getTotalPrice, BigDecimal::add)); | ||
| 92 | - }); | 71 | + // 2. 获得统计数据 |
| 72 | + return funnelMapper.selectBusinessSummaryListGroupByEndStatus(reqVO); | ||
| 93 | } | 73 | } |
| 94 | 74 | ||
| 95 | @Override | 75 | @Override |
| @@ -101,26 +81,20 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | @@ -101,26 +81,20 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | ||
| 101 | } | 81 | } |
| 102 | 82 | ||
| 103 | // 2. 按天统计,获取分项统计数据 | 83 | // 2. 按天统计,获取分项统计数据 |
| 104 | - // TODO @puhui999:可以这个统计,返回的时候,就把数量、金额一起统计好; | ||
| 105 | - List<CrmStatisticsBusinessSummaryByDateRespVO> businessCreateCountList = funnelMapper.selectBusinessCreateCountGroupByDate(reqVO); | ||
| 106 | - List<CrmBusinessDO> businessList = businessService.getBusinessListByOwnerUserIdsAndDate(reqVO.getUserIds(), reqVO.getTimes()); | ||
| 107 | - Map<String, BigDecimal> businessDealCountMap = businessList.stream().collect(Collectors.groupingBy(business -> | ||
| 108 | - business.getCreateTime().format(DateTimeFormatter.ofPattern(FORMAT_YEAR_MONTH_DAY)), | ||
| 109 | - Collectors.reducing(BigDecimal.ZERO, CrmBusinessDO::getTotalPrice, BigDecimal::add))); | ||
| 110 | - | 84 | + List<CrmStatisticsBusinessSummaryByDateRespVO> businessSummaryList = funnelMapper.selectBusinessSummaryGroupByDate(reqVO); |
| 111 | // 3. 按照日期间隔,合并数据 | 85 | // 3. 按照日期间隔,合并数据 |
| 112 | List<LocalDateTime[]> timeRanges = LocalDateTimeUtils.getDateRangeList(reqVO.getTimes()[0], reqVO.getTimes()[1], reqVO.getInterval()); | 86 | List<LocalDateTime[]> timeRanges = LocalDateTimeUtils.getDateRangeList(reqVO.getTimes()[0], reqVO.getTimes()[1], reqVO.getInterval()); |
| 113 | return convertList(timeRanges, times -> { | 87 | return convertList(timeRanges, times -> { |
| 114 | - Integer businessCreateCount = businessCreateCountList.stream() | 88 | + Integer businessCreateCount = businessSummaryList.stream() |
| 115 | .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime())) | 89 | .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime())) |
| 116 | .mapToInt(CrmStatisticsBusinessSummaryByDateRespVO::getBusinessCreateCount).sum(); | 90 | .mapToInt(CrmStatisticsBusinessSummaryByDateRespVO::getBusinessCreateCount).sum(); |
| 117 | - BigDecimal businessDealCount = businessDealCountMap.entrySet().stream() | ||
| 118 | - .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getKey())) | ||
| 119 | - .map(Map.Entry::getValue) | 91 | + BigDecimal businessDealCount = businessSummaryList.stream() |
| 92 | + .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime())) | ||
| 93 | + .map(CrmStatisticsBusinessSummaryByDateRespVO::getTotalPrice) | ||
| 120 | .reduce(BigDecimal.ZERO, BigDecimal::add); | 94 | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| 121 | return new CrmStatisticsBusinessSummaryByDateRespVO() | 95 | return new CrmStatisticsBusinessSummaryByDateRespVO() |
| 122 | .setTime(LocalDateTimeUtils.formatDateRange(times[0], times[1], reqVO.getInterval())) | 96 | .setTime(LocalDateTimeUtils.formatDateRange(times[0], times[1], reqVO.getInterval())) |
| 123 | - .setBusinessCreateCount(businessCreateCount).setBusinessDealCount(businessDealCount); | 97 | + .setBusinessCreateCount(businessCreateCount).setTotalPrice(businessDealCount); |
| 124 | }); | 98 | }); |
| 125 | } | 99 | } |
| 126 | 100 | ||
| @@ -132,7 +106,7 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | @@ -132,7 +106,7 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic | ||
| 132 | return PageResult.empty(); | 106 | return PageResult.empty(); |
| 133 | } | 107 | } |
| 134 | // 2. 执行查询 | 108 | // 2. 执行查询 |
| 135 | - return businessService.getBusinessPageByDate(pageVO.getUserIds(), pageVO.getTimes(), pageVO.getPageNo(), pageVO.getPageSize()); | 109 | + return businessService.getBusinessPageByDate(pageVO); |
| 136 | } | 110 | } |
| 137 | 111 | ||
| 138 | /** | 112 | /** |
yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsFunnelMapper.xml
| @@ -2,18 +2,61 @@ | @@ -2,18 +2,61 @@ | ||
| 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| 3 | <mapper namespace="cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsFunnelMapper"> | 3 | <mapper namespace="cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsFunnelMapper"> |
| 4 | 4 | ||
| 5 | - <select id="selectBusinessCreateCountGroupByDate" | 5 | + <select id="selectCustomerCountByDate" resultType="java.lang.Long"> |
| 6 | + SELECT COUNT(*) | ||
| 7 | + FROM crm_customer | ||
| 8 | + WHERE deleted = 0 | ||
| 9 | + AND owner_user_id IN | ||
| 10 | + <foreach collection="userIds" item="userId" open="(" close=")" separator=","> | ||
| 11 | + #{userId} | ||
| 12 | + </foreach> | ||
| 13 | + AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND | ||
| 14 | + #{times[1],javaType=java.time.LocalDateTime} | ||
| 15 | + </select> | ||
| 16 | + | ||
| 17 | + <select id="selectBusinessCountByDateAndEndStatus" resultType="java.lang.Long"> | ||
| 18 | + SELECT COUNT(*) | ||
| 19 | + FROM crm_business | ||
| 20 | + WHERE deleted = 0 | ||
| 21 | + <if test="status != null"> | ||
| 22 | + AND end_status = #{status} | ||
| 23 | + </if> | ||
| 24 | + AND owner_user_id IN | ||
| 25 | + <foreach collection="reqVO.userIds" item="userId" open="(" close=")" separator=","> | ||
| 26 | + #{userId} | ||
| 27 | + </foreach> | ||
| 28 | + AND create_time BETWEEN #{reqVO.times[0],javaType=java.time.LocalDateTime} AND | ||
| 29 | + #{reqVO.times[1],javaType=java.time.LocalDateTime} | ||
| 30 | + </select> | ||
| 31 | + | ||
| 32 | + <select id="selectBusinessSummaryListGroupByEndStatus" | ||
| 33 | + resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByEndStatusRespVO"> | ||
| 34 | + SELECT end_status AS endStatus,COUNT(*) AS businessCount, SUM(total_price) AS totalPrice | ||
| 35 | + FROM crm_business | ||
| 36 | + WHERE deleted = 0 AND end_status IS NOT NULL | ||
| 37 | + AND owner_user_id IN | ||
| 38 | + <foreach collection="userIds" item="userId" open="(" close=")" separator=","> | ||
| 39 | + #{userId} | ||
| 40 | + </foreach> | ||
| 41 | + AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND | ||
| 42 | + #{times[1],javaType=java.time.LocalDateTime} | ||
| 43 | + GROUP BY end_status | ||
| 44 | + </select> | ||
| 45 | + | ||
| 46 | + <select id="selectBusinessSummaryGroupByDate" | ||
| 6 | resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO"> | 47 | resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO"> |
| 7 | SELECT | 48 | SELECT |
| 8 | - DATE_FORMAT(create_time, '%Y-%m-%d') AS time, | ||
| 9 | - COUNT(*) AS businessCreateCount | 49 | + DATE_FORMAT(create_time, '%Y-%m-%d') AS time, |
| 50 | + COUNT(*) AS businessCreateCount, | ||
| 51 | + SUM(total_price) AS totalPrice | ||
| 10 | FROM crm_business | 52 | FROM crm_business |
| 11 | WHERE deleted = 0 | 53 | WHERE deleted = 0 |
| 12 | AND owner_user_id IN | 54 | AND owner_user_id IN |
| 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} | 55 | + <foreach collection="userIds" item="userId" open="(" close=")" separator=","> |
| 56 | + #{userId} | ||
| 57 | + </foreach> | ||
| 58 | + AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND | ||
| 59 | + #{times[1],javaType=java.time.LocalDateTime} | ||
| 17 | GROUP BY time | 60 | GROUP BY time |
| 18 | </select> | 61 | </select> |
| 19 | 62 |