mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-01-19 03:30:06 +08:00
!902 fix: [CRM-客户统计]根据Code-Review 修改
Merge pull request !902 from dhb52/develop
This commit is contained in:
commit
85817a2426
@ -1,39 +1,68 @@
|
||||
### 新建客户总量分析(按日)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-total-customer-count?deptId=100×[0]=2024-12-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
# == 1. 客户总量分析 ==
|
||||
### 1.1 客户总量分析(按日)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-customer-summary-by-date?deptId=100×[0]=2024-01-01 00:00:00×[1]=2024-01-29 23:59:59
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
### 新建客户总量分析(按月)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-total-customer-count?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
### 1.2 客户总量分析(按月)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-customer-summary-by-date?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
### 成交客户总量分析(按日)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-deal-total-customer-count?deptId=100×[0]=2024-12-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
### 1.3 客户总量统计(按用户)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-customer-summary-by-user?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
### 成交客户总量分析(按月)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-deal-total-customer-count?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
|
||||
# == 2. 客户跟进次数分析 ==
|
||||
### 2.1 客户跟进次数分析(按日)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-followup-summary-by-date?deptId=100×[0]=2024-01-01 00:00:00×[1]=2024-01-29 23:59:59
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
### 获取客户跟进次数(按日)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-record-count?deptId=100×[0]=2024-12-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
### 2.2 客户跟进次数分析(按月)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-followup-summary-by-date?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
### 获取客户跟进次数(按月)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-record-count?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
### 2.3 客户总量统计(按用户)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-followup-summary-by-user?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
### 获取已跟进客户数(按日)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-distinct-record-count?deptId=100×[0]=2024-12-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
|
||||
# == 3. 客户跟进方式分析 ==
|
||||
### 3.1 客户跟进方式分析
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-followup-summary-by-type?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
### 获取已跟进客户数(按月)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-distinct-record-count?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
|
||||
# == 4. 客户成交周期 ==
|
||||
### 4.1 合同摘要信息(客户转化率页面)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-contract-summary?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
|
||||
# == 5. 客户成交周期 ==
|
||||
### 5.1 客户成交周期(按日)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-customer-deal-cycle-by-date?deptId=100×[0]=2024-01-01 00:00:00×[1]=2024-01-29 23:59:59
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
### 5.2 客户成交周期(按月)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-customer-deal-cycle-by-date?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
### 5.3 获取客户成交周期(按用户)
|
||||
GET {{baseUrl}}/crm/statistics-customer/get-customer-deal-cycle-by-user?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
tenant-id: {{adminTenentId}}
|
@ -1,8 +1,7 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerCountVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.*;
|
||||
import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsCustomerService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@ -18,8 +17,7 @@ import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
// TODO @dhb52:数据统计 员工客户分析,改成“客户统计”
|
||||
@Tag(name = "管理后台 - CRM 数据统计 员工客户分析")
|
||||
@Tag(name = "管理后台 - CRM 客户统计")
|
||||
@RestController
|
||||
@RequestMapping("/crm/statistics-customer")
|
||||
@Validated
|
||||
@ -28,50 +26,60 @@ public class CrmStatisticsCustomerController {
|
||||
@Resource
|
||||
private CrmStatisticsCustomerService customerService;
|
||||
|
||||
// TODO @dhb52:建议 getCustomerCount 和 getDealTotalCustomerCount 搞成一个接口;
|
||||
// 1. 数量接口:【方法:getCustomerSummaryByDate】,VO:CrmStatisticsCustomerSummaryByDateRespVO,然后里面是 time、customerCreateCount customerDealCount
|
||||
// 2. 按人统计:【方法:getCustomerSummaryByUser】,VO:CrmStatisticsCustomerSummaryByOwnerRespVO,然后里面是 ownerUserId、ownerUserName、customerCreateCount customerDealCount、contractPrice、receivablePrice;客户成交率、未回款金额、回款完成率,交给前端计算;
|
||||
|
||||
@GetMapping("/get-total-customer-count")
|
||||
@Operation(summary = "获得新建客户数量")
|
||||
@GetMapping("/get-customer-summary-by-date")
|
||||
@Operation(summary = "获取客户总量分析(按日期)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsCustomerCountVO>> getTotalCustomerCount(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getTotalCustomerCount(reqVO));
|
||||
public CommonResult<List<CrmStatisticsCustomerSummaryByDateRespVO>> getCustomerSummaryByDate(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getCustomerSummaryByDate(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-deal-total-customer-count")
|
||||
@Operation(summary = "获得成交客户数量")
|
||||
@GetMapping("/get-customer-summary-by-user")
|
||||
@Operation(summary = "获取客户总量分析(按用户)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsCustomerCountVO>> getDealTotalCustomerCount(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getDealTotalCustomerCount(reqVO));
|
||||
public CommonResult<List<CrmStatisticsCustomerSummaryByUserRespVO>> getCustomerSummaryByUser(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getCustomerSummaryByUser(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-record-count")
|
||||
@Operation(summary = "获取客户跟进次数")
|
||||
@GetMapping("/get-followup-summary-by-date")
|
||||
@Operation(summary = "获取客户跟进次数分析(按日期)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsCustomerCountVO>> getRecordCount(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getRecordCount(reqVO));
|
||||
public CommonResult<List<CrmStatisticsFollowupSummaryByDateRespVO>> getFollowupSummaryByDate(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getFollowupSummaryByDate(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-distinct-record-count")
|
||||
@Operation(summary = "获取已跟进客户数")
|
||||
@GetMapping("/get-followup-summary-by-user")
|
||||
@Operation(summary = "获取客户跟进次数分析(按用户)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsCustomerCountVO>> getDistinctRecordCount(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getDistinctRecordCount(reqVO));
|
||||
public CommonResult<List<CrmStatisticsFollowupSummaryByUserRespVO>> getFollowupSummaryByUser(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getFollowupSummaryByUser(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-record-type-count")
|
||||
@Operation(summary = "获取客户跟进方式统计数")
|
||||
@GetMapping("/get-followup-summary-by-type")
|
||||
@Operation(summary = "获取客户跟进次数分析(按类型)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsCustomerCountVO>> getRecordTypeCount(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getRecordTypeCount(reqVO));
|
||||
public CommonResult<List<CrmStatisticsFollowupSummaryByTypeRespVO>> getFollowupSummaryByType(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getFollowupSummaryByType(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-customer-cycle")
|
||||
@Operation(summary = "获取客户成交周期")
|
||||
@GetMapping("/get-contract-summary")
|
||||
@Operation(summary = "获取合同摘要信息(客户转化率页面)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsCustomerCountVO>> getCustomerCycle(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getCustomerCycle(reqVO));
|
||||
public CommonResult<List<CrmStatisticsCustomerContractSummaryRespVO>> getContractSummary(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getContractSummary(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-customer-deal-cycle-by-date")
|
||||
@Operation(summary = "获取客户成交周期(按日期)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsCustomerDealCycleByDateRespVO>> getCustomerDealCycleByDate(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getCustomerDealCycleByDate(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-customer-deal-cycle-by-user")
|
||||
@Operation(summary = "获取客户成交周期(按用户)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsCustomerDealCycleByUserRespVO>> getCustomerDealCycleByUser(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getCustomerDealCycleByUser(reqVO));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 用户客户统计响应 Base VO
|
||||
*/
|
||||
@Data
|
||||
public class CrmStatisticsCustomerByUserBaseRespVO {
|
||||
|
||||
@Schema(description = "负责人ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@JsonIgnore
|
||||
private Long ownerUserId;
|
||||
|
||||
@Schema(description = "负责人", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
|
||||
private String ownerUserName;
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 客户转化率分析 VO")
|
||||
@Data
|
||||
public class CrmStatisticsCustomerContractSummaryRespVO {
|
||||
|
||||
@Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
|
||||
private String customerName;
|
||||
|
||||
@Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "演示合同")
|
||||
private String contractName;
|
||||
|
||||
@Schema(description = "合同总金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1200.00")
|
||||
private BigDecimal totalPrice;
|
||||
|
||||
@Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1200.00")
|
||||
private BigDecimal receivablePrice;
|
||||
|
||||
@Schema(description = "客户行业ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@JsonIgnore
|
||||
private String industryId;
|
||||
|
||||
@Schema(description = "客户行业", requiredMode = Schema.RequiredMode.REQUIRED, example = "金融")
|
||||
private String industryName;
|
||||
|
||||
@Schema(description = "客户来源ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@JsonIgnore
|
||||
private String source;
|
||||
|
||||
@Schema(description = "客户来源", requiredMode = Schema.RequiredMode.REQUIRED, example = "外呼")
|
||||
private String sourceName;
|
||||
|
||||
@Schema(description = "负责人ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@JsonIgnore
|
||||
private Long ownerUserId;
|
||||
|
||||
@Schema(description = "负责人", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
|
||||
private String ownerUserName;
|
||||
|
||||
@Schema(description = "创建人ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@JsonIgnore
|
||||
private String creatorUserId;
|
||||
|
||||
@Schema(description = "创建人", requiredMode = Schema.RequiredMode.REQUIRED, example = "源码")
|
||||
private String creatorUserName;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-01 13:24:26")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02 00:00:00")
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY, timezone = TIME_ZONE_DEFAULT)
|
||||
private LocalDate orderDate;
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@Schema(description = "管理后台 - CRM 数据统计 员工客户分析 VO")
|
||||
@Data
|
||||
public class CrmStatisticsCustomerCountVO {
|
||||
|
||||
/**
|
||||
* 时间轴
|
||||
* <p>
|
||||
* group by DATE_FORMAT(create_date, '%Y%m')
|
||||
*/
|
||||
@Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 数量是个特别“抽象”的概念,在不同排行下,代表不同含义
|
||||
* <p>
|
||||
* 1. 金额:合同金额排行、回款金额排行
|
||||
* 2. 个数:签约合同排行、产品销量排行、产品销量排行、新增客户数排行、新增联系人排行、跟进次数排行、跟进客户数排行
|
||||
*/
|
||||
@Schema(description = "数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer count = 0;
|
||||
|
||||
/**
|
||||
* 成交周期(天)
|
||||
*/
|
||||
@Schema(description = "成交周期", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0")
|
||||
private Double cycle = 0.0;
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 客户成交周期分析(按日期) VO")
|
||||
@Data
|
||||
public class CrmStatisticsCustomerDealCycleByDateRespVO {
|
||||
|
||||
@Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
|
||||
private String time;
|
||||
|
||||
@Schema(description = "成交周期", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0")
|
||||
private Double customerDealCycle = 0.0;
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 成交周期分析(按用户) VO")
|
||||
@Data
|
||||
public class CrmStatisticsCustomerDealCycleByUserRespVO extends CrmStatisticsCustomerByUserBaseRespVO {
|
||||
|
||||
@Schema(description = "成交周期", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0")
|
||||
private Double customerDealCycle = 0.0;
|
||||
|
||||
@Schema(description = "成交客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer customerDealCount = 0;
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 客户总量分析(按日期) VO")
|
||||
@Data
|
||||
public class CrmStatisticsCustomerSummaryByDateRespVO {
|
||||
|
||||
@Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
|
||||
private String time;
|
||||
|
||||
@Schema(description = "新建客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer customerCreateCount = 0;
|
||||
|
||||
@Schema(description = "成交客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer customerDealCount = 0;
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 客户总量分析(按用户) VO")
|
||||
@Data
|
||||
public class CrmStatisticsCustomerSummaryByUserRespVO extends CrmStatisticsCustomerByUserBaseRespVO {
|
||||
|
||||
@Schema(description = "新建客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer customerCreateCount = 0;
|
||||
|
||||
@Schema(description = "成交客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer customerDealCount = 0;
|
||||
|
||||
@Schema(description = "合同总金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
|
||||
private BigDecimal contractPrice = BigDecimal.ZERO;
|
||||
|
||||
@Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
|
||||
private BigDecimal receivablePrice = BigDecimal.ZERO;
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 跟进次数分析(按日期) VO")
|
||||
@Data
|
||||
public class CrmStatisticsFollowupSummaryByDateRespVO {
|
||||
|
||||
@Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
|
||||
private String time;
|
||||
|
||||
@Schema(description = "跟进次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer followupRecordCount = 0;
|
||||
|
||||
@Schema(description = "跟进客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer followupCustomerCount = 0;
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 跟进次数分析(按类型) VO")
|
||||
@Data
|
||||
public class CrmStatisticsFollowupSummaryByTypeRespVO {
|
||||
|
||||
@Schema(description = "跟进类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private String followupType;
|
||||
|
||||
@Schema(description = "跟进次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer followupRecordCount = 0;
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 跟进次数分析(按用户) VO")
|
||||
@Data
|
||||
public class CrmStatisticsFollowupSummaryByUserRespVO extends CrmStatisticsCustomerByUserBaseRespVO {
|
||||
|
||||
@Schema(description = "跟进次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer followupRecordCount = 0;
|
||||
|
||||
@Schema(description = "跟进客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer followupCustomerCount = 0;
|
||||
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package cn.iocoder.yudao.module.crm.dal.mysql.statistics;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerCountVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.*;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
@ -14,16 +13,32 @@ import java.util.List;
|
||||
@Mapper
|
||||
public interface CrmStatisticsCustomerMapper {
|
||||
|
||||
List<CrmStatisticsCustomerCountVO> selectCustomerCountGroupbyDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByDateRespVO> selectCustomerCreateCountGroupbyDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
List<CrmStatisticsCustomerCountVO> selectDealCustomerCountGroupbyDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByDateRespVO> selectCustomerDealCountGroupbyDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
List<CrmStatisticsCustomerCountVO> selectRecordCountGroupbyDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByUserRespVO> selectCustomerCreateCountGroupbyUser(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
List<CrmStatisticsCustomerCountVO> selectDistinctRecordCountGroupbyDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByUserRespVO> selectCustomerDealCountGroupbyUser(CrmStatisticsCustomerReqVO crmStatisticsCustomerReqVO);
|
||||
|
||||
List<CrmStatisticsCustomerCountVO> selectRecordCountGroupbyType(CrmStatisticsCustomerReqVO reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByUserRespVO> selectContractPriceGroupbyUser(CrmStatisticsCustomerReqVO crmStatisticsCustomerReqVO);
|
||||
|
||||
List<CrmStatisticsCustomerCountVO> selectCustomerCycleGroupbyDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByUserRespVO> selectReceivablePriceGroupbyUser(CrmStatisticsCustomerReqVO crmStatisticsCustomerReqVO);
|
||||
|
||||
List<CrmStatisticsFollowupSummaryByDateRespVO> selectFollowupRecordCountGroupbyDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
List<CrmStatisticsFollowupSummaryByDateRespVO> selectFollowupCustomerCountGroupbyDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
List<CrmStatisticsFollowupSummaryByUserRespVO> selectFollowupRecordCountGroupbyUser(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
List<CrmStatisticsFollowupSummaryByUserRespVO> selectFollowupCustomerCountGroupbyUser(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
List<CrmStatisticsCustomerContractSummaryRespVO> selectContractSummary(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
List<CrmStatisticsFollowupSummaryByTypeRespVO> selectFollowupRecordCountGroupbyType(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
List<CrmStatisticsCustomerDealCycleByDateRespVO> selectCustomerDealCycleGroupbyDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
List<CrmStatisticsCustomerDealCycleByUserRespVO> selectCustomerDealCycleGroupbyUser(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
}
|
||||
|
@ -1,64 +1,80 @@
|
||||
package cn.iocoder.yudao.module.crm.service.statistics;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerCountVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CRM 数据统计 员工客户分析 Service 接口
|
||||
* CRM 客户分析 Service 接口
|
||||
*
|
||||
* @author dhb52
|
||||
*/
|
||||
public interface CrmStatisticsCustomerService {
|
||||
|
||||
/**
|
||||
* 获取新建客户数量
|
||||
* 总量分析(按日期)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 新建客户数量统计
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsCustomerCountVO> getTotalCustomerCount(CrmStatisticsCustomerReqVO reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByDateRespVO> getCustomerSummaryByDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 获取成交客户数量
|
||||
* 总量分析(按用户)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 成交客户数量统计
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsCustomerCountVO> getDealTotalCustomerCount(CrmStatisticsCustomerReqVO reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByUserRespVO> getCustomerSummaryByUser(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
|
||||
/**
|
||||
* 获取客户跟进次数
|
||||
* 跟进次数分析(按日期)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 客户跟进次数
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsCustomerCountVO> getRecordCount(CrmStatisticsCustomerReqVO reqVO);
|
||||
List<CrmStatisticsFollowupSummaryByDateRespVO> getFollowupSummaryByDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 获取已跟进客户数
|
||||
* 跟进次数分析(按用户)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 已跟进客户数
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsCustomerCountVO> getDistinctRecordCount(CrmStatisticsCustomerReqVO reqVO);
|
||||
List<CrmStatisticsFollowupSummaryByUserRespVO> getFollowupSummaryByUser(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 获取客户跟进方式统计数
|
||||
* 客户跟进次数分析(按类型)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 客户跟进方式统计数
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsCustomerCountVO> getRecordTypeCount(CrmStatisticsCustomerReqVO reqVO);
|
||||
List<CrmStatisticsFollowupSummaryByTypeRespVO> getFollowupSummaryByType(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
|
||||
/**
|
||||
* 获取客户成交周期
|
||||
* 获取合同摘要信息(客户转化率页面)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 客户成交周期
|
||||
* @return 合同摘要列表
|
||||
*/
|
||||
List<CrmStatisticsCustomerCountVO> getCustomerCycle(CrmStatisticsCustomerReqVO reqVO);
|
||||
List<CrmStatisticsCustomerContractSummaryRespVO> getContractSummary(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 客户成交周期(按日期)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsCustomerDealCycleByDateRespVO> getCustomerDealCycleByDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 客户成交周期(按用户)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsCustomerDealCycleByUserRespVO> getCustomerDealCycleByUser(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
}
|
||||
|
@ -3,8 +3,9 @@ package cn.iocoder.yudao.module.crm.service.statistics;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerCountVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerReqVO;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.*;
|
||||
import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsCustomerMapper;
|
||||
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
@ -17,17 +18,19 @@ import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.*;
|
||||
|
||||
/**
|
||||
* CRM 数据统计 员工客户分析 Service 实现类
|
||||
* CRM 客户分析 Service 实现类
|
||||
*
|
||||
* @author dhb52
|
||||
*/
|
||||
@ -35,6 +38,13 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
|
||||
@Validated
|
||||
public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerService {
|
||||
|
||||
private static final String SQL_DATE_FORMAT_BY_MONTH = "%Y%m";
|
||||
private static final String SQL_DATE_FORMAT_BY_DAY = "%Y%m%d";
|
||||
|
||||
private static final String TIME_FORMAT_BY_MONTH = "yyyyMM";
|
||||
private static final String TIME_FORMAT_BY_DAY = "yyyyMMdd";
|
||||
|
||||
|
||||
@Resource
|
||||
private CrmStatisticsCustomerMapper customerMapper;
|
||||
|
||||
@ -45,130 +55,354 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
@Resource
|
||||
private DictDataApi dictDataApi;
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsCustomerCountVO> getTotalCustomerCount(CrmStatisticsCustomerReqVO reqVO) {
|
||||
return getStat(reqVO, customerMapper::selectCustomerCountGroupbyDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsCustomerCountVO> getDealTotalCustomerCount(CrmStatisticsCustomerReqVO reqVO) {
|
||||
return getStat(reqVO, customerMapper::selectDealCustomerCountGroupbyDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsCustomerCountVO> getRecordCount(CrmStatisticsCustomerReqVO reqVO) {
|
||||
reqVO.setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType());
|
||||
return getStat(reqVO, customerMapper::selectRecordCountGroupbyDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsCustomerCountVO> getDistinctRecordCount(CrmStatisticsCustomerReqVO reqVO) {
|
||||
reqVO.setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType());
|
||||
return getStat(reqVO, customerMapper::selectDistinctRecordCountGroupbyDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsCustomerCountVO> getRecordTypeCount(CrmStatisticsCustomerReqVO reqVO) {
|
||||
// 1. 获得用户编号数组: 如果用户编号为空, 则获得部门下的用户编号数组
|
||||
if (ObjUtil.isNotNull(reqVO.getUserId())) {
|
||||
reqVO.setUserIds(List.of(reqVO.getUserId()));
|
||||
} else {
|
||||
reqVO.setUserIds(getUserIds(reqVO.getDeptId()));
|
||||
}
|
||||
if (CollUtil.isEmpty(reqVO.getUserIds())) {
|
||||
public List<CrmStatisticsCustomerSummaryByDateRespVO> getCustomerSummaryByDate(CrmStatisticsCustomerReqVO reqVO) {
|
||||
// 1. 获得用户编号数组
|
||||
final List<Long> userIds = getUserIds(reqVO);
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取分项统计数据
|
||||
reqVO.setSqlDateFormat(getSqlDateFormat(reqVO.getTimes()[0], reqVO.getTimes()[1]));
|
||||
final List<CrmStatisticsCustomerSummaryByDateRespVO> customerCreateCount = customerMapper.selectCustomerCreateCountGroupbyDate(reqVO);
|
||||
final List<CrmStatisticsCustomerSummaryByDateRespVO> customerDealCount = customerMapper.selectCustomerDealCountGroupbyDate(reqVO);
|
||||
|
||||
// 3. 获取时间序列
|
||||
final List<String> times = generateTimeSeries(reqVO.getTimes()[0], reqVO.getTimes()[1]);
|
||||
|
||||
// 4. 合并统计数据
|
||||
List<CrmStatisticsCustomerSummaryByDateRespVO> respVoList = new ArrayList<>(times.size());
|
||||
final Map<String, Integer> customerCreateCountMap = convertMap(customerCreateCount,
|
||||
CrmStatisticsCustomerSummaryByDateRespVO::getTime,
|
||||
CrmStatisticsCustomerSummaryByDateRespVO::getCustomerCreateCount);
|
||||
final Map<String, Integer> customerDealCountMap = convertMap(customerDealCount,
|
||||
CrmStatisticsCustomerSummaryByDateRespVO::getTime,
|
||||
CrmStatisticsCustomerSummaryByDateRespVO::getCustomerDealCount);
|
||||
times.forEach(time -> respVoList.add(
|
||||
new CrmStatisticsCustomerSummaryByDateRespVO().setTime(time)
|
||||
.setCustomerCreateCount(customerCreateCountMap.getOrDefault(time, 0))
|
||||
.setCustomerDealCount(customerDealCountMap.getOrDefault(time, 0))
|
||||
));
|
||||
|
||||
return respVoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsCustomerSummaryByUserRespVO> getCustomerSummaryByUser(CrmStatisticsCustomerReqVO reqVO) {
|
||||
// 1. 获得用户编号数组
|
||||
final List<Long> userIds = getUserIds(reqVO);
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取分项统计数据
|
||||
final List<CrmStatisticsCustomerSummaryByUserRespVO> customerCreateCount = customerMapper.selectCustomerCreateCountGroupbyUser(reqVO);
|
||||
final List<CrmStatisticsCustomerSummaryByUserRespVO> customerDealCount = customerMapper.selectCustomerDealCountGroupbyUser(reqVO);
|
||||
final List<CrmStatisticsCustomerSummaryByUserRespVO> contractPrice = customerMapper.selectContractPriceGroupbyUser(reqVO);
|
||||
final List<CrmStatisticsCustomerSummaryByUserRespVO> receivablePrice = customerMapper.selectReceivablePriceGroupbyUser(reqVO);
|
||||
|
||||
// 3. 合并统计数据
|
||||
final Map<Long, Integer> customerCreateCountMap = convertMap(customerCreateCount,
|
||||
CrmStatisticsCustomerSummaryByUserRespVO::getOwnerUserId,
|
||||
CrmStatisticsCustomerSummaryByUserRespVO::getCustomerCreateCount);
|
||||
final Map<Long, Integer> customerDealCountMap = convertMap(customerDealCount,
|
||||
CrmStatisticsCustomerSummaryByUserRespVO::getOwnerUserId,
|
||||
CrmStatisticsCustomerSummaryByUserRespVO::getCustomerDealCount);
|
||||
final Map<Long, BigDecimal> contractPriceMap = convertMap(contractPrice,
|
||||
CrmStatisticsCustomerSummaryByUserRespVO::getOwnerUserId,
|
||||
CrmStatisticsCustomerSummaryByUserRespVO::getContractPrice);
|
||||
final Map<Long, BigDecimal> receivablePriceMap = convertMap(receivablePrice,
|
||||
CrmStatisticsCustomerSummaryByUserRespVO::getOwnerUserId,
|
||||
CrmStatisticsCustomerSummaryByUserRespVO::getReceivablePrice);
|
||||
List<CrmStatisticsCustomerSummaryByUserRespVO> respVoList = new ArrayList<>(userIds.size());
|
||||
userIds.forEach(userId -> {
|
||||
final CrmStatisticsCustomerSummaryByUserRespVO vo = new CrmStatisticsCustomerSummaryByUserRespVO();
|
||||
vo.setOwnerUserId(userId);
|
||||
vo.setCustomerCreateCount(customerCreateCountMap.getOrDefault(userId, 0))
|
||||
.setCustomerDealCount(customerDealCountMap.getOrDefault(userId, 0))
|
||||
.setContractPrice(contractPriceMap.getOrDefault(userId, BigDecimal.ZERO))
|
||||
.setReceivablePrice(receivablePriceMap.getOrDefault(userId, BigDecimal.ZERO));
|
||||
respVoList.add(vo);
|
||||
});
|
||||
|
||||
// 4. 拼接用户信息
|
||||
appendUserInfo(respVoList);
|
||||
|
||||
return respVoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsFollowupSummaryByDateRespVO> getFollowupSummaryByDate(CrmStatisticsCustomerReqVO reqVO) {
|
||||
// 1. 获得用户编号数组
|
||||
final List<Long> userIds = getUserIds(reqVO);
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取分项统计数据
|
||||
reqVO.setSqlDateFormat(getSqlDateFormat(reqVO.getTimes()[0], reqVO.getTimes()[1]));
|
||||
reqVO.setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType());
|
||||
final List<CrmStatisticsFollowupSummaryByDateRespVO> followupRecordCount = customerMapper.selectFollowupRecordCountGroupbyDate(reqVO);
|
||||
final List<CrmStatisticsFollowupSummaryByDateRespVO> followupCustomerCount = customerMapper.selectFollowupCustomerCountGroupbyDate(reqVO);
|
||||
|
||||
// 3. 获取时间序列
|
||||
final List<String> times = generateTimeSeries(reqVO.getTimes()[0], reqVO.getTimes()[1]);
|
||||
|
||||
// 4. 合并统计数据
|
||||
List<CrmStatisticsFollowupSummaryByDateRespVO> respVoList = new ArrayList<>(times.size());
|
||||
final Map<String, Integer> followupRecordCountMap = convertMap(followupRecordCount,
|
||||
CrmStatisticsFollowupSummaryByDateRespVO::getTime,
|
||||
CrmStatisticsFollowupSummaryByDateRespVO::getFollowupRecordCount);
|
||||
final Map<String, Integer> followupCustomerCountMap = convertMap(followupCustomerCount,
|
||||
CrmStatisticsFollowupSummaryByDateRespVO::getTime,
|
||||
CrmStatisticsFollowupSummaryByDateRespVO::getFollowupCustomerCount);
|
||||
times.forEach(time -> respVoList.add(
|
||||
new CrmStatisticsFollowupSummaryByDateRespVO().setTime(time)
|
||||
.setFollowupRecordCount(followupRecordCountMap.getOrDefault(time, 0))
|
||||
.setFollowupCustomerCount(followupCustomerCountMap.getOrDefault(time, 0))
|
||||
));
|
||||
|
||||
return respVoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsFollowupSummaryByUserRespVO> getFollowupSummaryByUser(CrmStatisticsCustomerReqVO reqVO) {
|
||||
// 1. 获得用户编号数组
|
||||
final List<Long> userIds = getUserIds(reqVO);
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取分项统计数据
|
||||
reqVO.setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType());
|
||||
final List<CrmStatisticsFollowupSummaryByUserRespVO> followupRecordCount = customerMapper.selectFollowupRecordCountGroupbyUser(reqVO);
|
||||
final List<CrmStatisticsFollowupSummaryByUserRespVO> followupCustomerCount = customerMapper.selectFollowupCustomerCountGroupbyUser(reqVO);
|
||||
|
||||
// 3. 合并统计数据
|
||||
final Map<Long, Integer> followupRecordCountMap = convertMap(followupRecordCount,
|
||||
CrmStatisticsFollowupSummaryByUserRespVO::getOwnerUserId,
|
||||
CrmStatisticsFollowupSummaryByUserRespVO::getFollowupRecordCount);
|
||||
final Map<Long, Integer> followupCustomerCountMap = convertMap(followupCustomerCount,
|
||||
CrmStatisticsFollowupSummaryByUserRespVO::getOwnerUserId,
|
||||
CrmStatisticsFollowupSummaryByUserRespVO::getFollowupCustomerCount);
|
||||
List<CrmStatisticsFollowupSummaryByUserRespVO> respVoList = new ArrayList<>(userIds.size());
|
||||
userIds.forEach(userId -> {
|
||||
final CrmStatisticsFollowupSummaryByUserRespVO vo = new CrmStatisticsFollowupSummaryByUserRespVO()
|
||||
.setFollowupRecordCount(followupRecordCountMap.getOrDefault(userId, 0))
|
||||
.setFollowupCustomerCount(followupCustomerCountMap.getOrDefault(userId, 0));
|
||||
vo.setOwnerUserId(userId);
|
||||
respVoList.add(vo);
|
||||
});
|
||||
|
||||
// 4. 拼接用户信息
|
||||
appendUserInfo(respVoList);
|
||||
|
||||
return respVoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsFollowupSummaryByTypeRespVO> getFollowupSummaryByType(CrmStatisticsCustomerReqVO reqVO) {
|
||||
// 1. 获得用户编号数组
|
||||
final List<Long> userIds = getUserIds(reqVO);
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获得排行数据
|
||||
reqVO.setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType());
|
||||
List<CrmStatisticsCustomerCountVO> stats = customerMapper.selectRecordCountGroupbyType(reqVO);
|
||||
List<CrmStatisticsFollowupSummaryByTypeRespVO> respVoList = customerMapper.selectFollowupRecordCountGroupbyType(reqVO);
|
||||
|
||||
// 3. 获取字典数据
|
||||
List<DictDataRespDTO> followUpTypes = dictDataApi.getDictDataList("crm_follow_up_type");
|
||||
final Map<String, String> followUpTypeMap = convertMap(followUpTypes, DictDataRespDTO::getValue, DictDataRespDTO::getLabel);
|
||||
stats.forEach(stat -> {
|
||||
stat.setCategory(followUpTypeMap.get(stat.getCategory()));
|
||||
List<DictDataRespDTO> followUpTypes = dictDataApi.getDictDataList(CRM_FOLLOW_UP_TYPE);
|
||||
final Map<String, String> followUpTypeMap = convertMap(followUpTypes,
|
||||
DictDataRespDTO::getValue, DictDataRespDTO::getLabel);
|
||||
respVoList.forEach(vo -> {
|
||||
vo.setFollowupType(followUpTypeMap.get(vo.getFollowupType()));
|
||||
});
|
||||
|
||||
return stats;
|
||||
return respVoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsCustomerCountVO> getCustomerCycle(CrmStatisticsCustomerReqVO reqVO) {
|
||||
return getStat(reqVO, customerMapper::selectCustomerCycleGroupbyDate);
|
||||
public List<CrmStatisticsCustomerContractSummaryRespVO> getContractSummary(CrmStatisticsCustomerReqVO reqVO) {
|
||||
// 1. 获得用户编号数组
|
||||
final List<Long> userIds = getUserIds(reqVO);
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取统计数据
|
||||
List<CrmStatisticsCustomerContractSummaryRespVO> respVoList = customerMapper.selectContractSummary(reqVO);
|
||||
|
||||
// 3. 设置 创建人、负责人、行业、来源
|
||||
// 获取客户所属行业
|
||||
Map<String, String> industryMap = convertMap(dictDataApi.getDictDataList(CRM_CUSTOMER_INDUSTRY),
|
||||
DictDataRespDTO::getValue, DictDataRespDTO::getLabel);
|
||||
// 获取客户来源
|
||||
Map<String, String> sourceMap = convertMap(dictDataApi.getDictDataList(CRM_CUSTOMER_SOURCE),
|
||||
DictDataRespDTO::getValue, DictDataRespDTO::getLabel);
|
||||
// 获取创建人、负责人列表
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSetByFlatMap(respVoList,
|
||||
vo -> Stream.of(NumberUtils.parseLong(vo.getCreatorUserId()), vo.getOwnerUserId())));
|
||||
|
||||
respVoList.forEach(vo -> {
|
||||
MapUtils.findAndThen(industryMap, vo.getIndustryId(), vo::setIndustryName);
|
||||
MapUtils.findAndThen(sourceMap, vo.getSource(), vo::setSourceName);
|
||||
MapUtils.findAndThen(userMap, NumberUtils.parseLong(vo.getCreatorUserId()),
|
||||
user -> vo.setCreatorUserName(user.getNickname()));
|
||||
MapUtils.findAndThen(userMap, vo.getOwnerUserId(), user -> vo.setOwnerUserName(user.getNickname()));
|
||||
});
|
||||
|
||||
return respVoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsCustomerDealCycleByDateRespVO> getCustomerDealCycleByDate(CrmStatisticsCustomerReqVO reqVO) {
|
||||
// 1. 获得用户编号数组
|
||||
final List<Long> userIds = getUserIds(reqVO);
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取分项统计数据
|
||||
reqVO.setSqlDateFormat(getSqlDateFormat(reqVO.getTimes()[0], reqVO.getTimes()[1]));
|
||||
reqVO.setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType());
|
||||
final List<CrmStatisticsCustomerDealCycleByDateRespVO> customerDealCycle = customerMapper.selectCustomerDealCycleGroupbyDate(reqVO);
|
||||
|
||||
// 3. 获取时间序列
|
||||
final List<String> times = generateTimeSeries(reqVO.getTimes()[0], reqVO.getTimes()[1]);
|
||||
|
||||
// 4. 合并统计数据
|
||||
List<CrmStatisticsCustomerDealCycleByDateRespVO> respVoList = new ArrayList<>(times.size());
|
||||
final Map<String, Double> customerDealCycleMap = convertMap(customerDealCycle,
|
||||
CrmStatisticsCustomerDealCycleByDateRespVO::getTime,
|
||||
CrmStatisticsCustomerDealCycleByDateRespVO::getCustomerDealCycle);
|
||||
times.forEach(time -> respVoList.add(
|
||||
new CrmStatisticsCustomerDealCycleByDateRespVO().setTime(time)
|
||||
.setCustomerDealCycle(customerDealCycleMap.getOrDefault(time, 0D))
|
||||
));
|
||||
|
||||
return respVoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsCustomerDealCycleByUserRespVO> getCustomerDealCycleByUser(CrmStatisticsCustomerReqVO reqVO) {
|
||||
// 1. 获得用户编号数组
|
||||
final List<Long> userIds = getUserIds(reqVO);
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取分项统计数据
|
||||
reqVO.setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType());
|
||||
final List<CrmStatisticsCustomerDealCycleByUserRespVO> customerDealCycle = customerMapper.selectCustomerDealCycleGroupbyUser(reqVO);
|
||||
final List<CrmStatisticsCustomerSummaryByUserRespVO> customerDealCount = customerMapper.selectCustomerDealCountGroupbyUser(reqVO);
|
||||
|
||||
// 3. 合并统计数据
|
||||
final Map<Long, Double> customerDealCycleMap = convertMap(customerDealCycle,
|
||||
CrmStatisticsCustomerDealCycleByUserRespVO::getOwnerUserId,
|
||||
CrmStatisticsCustomerDealCycleByUserRespVO::getCustomerDealCycle);
|
||||
final Map<Long, Integer> customerDealCountMap = convertMap(customerDealCount,
|
||||
CrmStatisticsCustomerSummaryByUserRespVO::getOwnerUserId,
|
||||
CrmStatisticsCustomerSummaryByUserRespVO::getCustomerDealCount);
|
||||
List<CrmStatisticsCustomerDealCycleByUserRespVO> respVoList = new ArrayList<>(userIds.size());
|
||||
userIds.forEach(userId -> {
|
||||
final CrmStatisticsCustomerDealCycleByUserRespVO vo = new CrmStatisticsCustomerDealCycleByUserRespVO()
|
||||
.setCustomerDealCycle(customerDealCycleMap.getOrDefault(userId, 0.0))
|
||||
.setCustomerDealCount(customerDealCountMap.getOrDefault(userId, 0));
|
||||
vo.setOwnerUserId(userId);
|
||||
respVoList.add(vo);
|
||||
});
|
||||
|
||||
// 4. 拼接用户信息
|
||||
appendUserInfo(respVoList);
|
||||
|
||||
return respVoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得统计数据
|
||||
* 拼接用户信息(昵称)
|
||||
*
|
||||
* @param reqVO 参数
|
||||
* @param statFunction 统计方法
|
||||
* @return 统计数据
|
||||
* @param respVoList 统计数据
|
||||
*/
|
||||
private List<CrmStatisticsCustomerCountVO> getStat(CrmStatisticsCustomerReqVO reqVO, Function<CrmStatisticsCustomerReqVO, List<CrmStatisticsCustomerCountVO>> statFunction) {
|
||||
// 1. 获得用户编号数组: 如果用户编号为空, 则获得部门下的用户编号数组
|
||||
private <T extends CrmStatisticsCustomerByUserBaseRespVO> void appendUserInfo(List<T> respVoList) {
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSet(respVoList,
|
||||
CrmStatisticsCustomerByUserBaseRespVO::getOwnerUserId));
|
||||
respVoList.forEach(vo -> MapUtils.findAndThen(userMap,
|
||||
vo.getOwnerUserId(), user -> vo.setOwnerUserName(user.getNickname())));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户编号数组。如果用户编号为空, 则获得部门下的用户编号数组,包括子部门的所有用户编号
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 用户编号数组
|
||||
*/
|
||||
private List<Long> getUserIds(CrmStatisticsCustomerReqVO reqVO) {
|
||||
if (ObjUtil.isNotNull(reqVO.getUserId())) {
|
||||
reqVO.setUserIds(List.of(reqVO.getUserId()));
|
||||
return List.of(reqVO.getUserId());
|
||||
} else {
|
||||
reqVO.setUserIds(getUserIds(reqVO.getDeptId()));
|
||||
}
|
||||
if (CollUtil.isEmpty(reqVO.getUserIds())) {
|
||||
return Collections.emptyList();
|
||||
// 1. 获得部门列表
|
||||
final Long deptId = reqVO.getDeptId();
|
||||
List<Long> deptIds = convertList(deptApi.getChildDeptList(deptId), DeptRespDTO::getId);
|
||||
deptIds.add(deptId);
|
||||
// 2. 获得用户编号
|
||||
return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 生成日期格式
|
||||
LocalDateTime startTime = reqVO.getTimes()[0];
|
||||
final LocalDateTime endTime = reqVO.getTimes()[1];
|
||||
final long days = LocalDateTimeUtil.between(startTime, endTime).toDays();
|
||||
boolean byMonth = days > 31;
|
||||
if (byMonth) {
|
||||
// 按月
|
||||
reqVO.setSqlDateFormat("%Y%m");
|
||||
} else {
|
||||
// 按日
|
||||
reqVO.setSqlDateFormat("%Y%m%d");
|
||||
}
|
||||
|
||||
// 3. 获得排行数据
|
||||
List<CrmStatisticsCustomerCountVO> stats = statFunction.apply(reqVO);
|
||||
/**
|
||||
* 判断是否按照 月粒度 统计
|
||||
*
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return 是, 按月粒度, 否则按天粒度统计。
|
||||
*/
|
||||
private boolean queryByMonth(LocalDateTime startTime, LocalDateTime endTime) {
|
||||
return LocalDateTimeUtil.between(startTime, endTime).toDays() > 31;
|
||||
}
|
||||
|
||||
// 4. 生成时间序列
|
||||
List<CrmStatisticsCustomerCountVO> result = CollUtil.newArrayList();
|
||||
/**
|
||||
* 生成时间序列
|
||||
*
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return 时间序列
|
||||
*/
|
||||
private List<String> generateTimeSeries(LocalDateTime startTime, LocalDateTime endTime) {
|
||||
boolean byMonth = queryByMonth(startTime, endTime);
|
||||
List<String> times = CollUtil.newArrayList();
|
||||
while (!startTime.isAfter(endTime)) {
|
||||
final String category = LocalDateTimeUtil.format(startTime, byMonth ? "yyyyMM" : "yyyyMMdd");
|
||||
result.add(new CrmStatisticsCustomerCountVO().setCategory(category));
|
||||
times.add(LocalDateTimeUtil.format(startTime, byMonth ? TIME_FORMAT_BY_MONTH : TIME_FORMAT_BY_DAY));
|
||||
if (byMonth)
|
||||
startTime = startTime.plusMonths(1);
|
||||
else
|
||||
startTime = startTime.plusDays(1);
|
||||
}
|
||||
|
||||
// 5. 使用时间序列填充结果
|
||||
final Map<String, CrmStatisticsCustomerCountVO> statMap = convertMap(stats,
|
||||
CrmStatisticsCustomerCountVO::getCategory,
|
||||
Function.identity());
|
||||
result.forEach(r -> {
|
||||
if (statMap.containsKey(r.getCategory())) {
|
||||
r.setCount(statMap.get(r.getCategory()).getCount())
|
||||
.setCycle(statMap.get(r.getCategory()).getCycle());
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
return times;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获得部门下的用户编号数组,包括子部门的
|
||||
* 获取 SQL 查询 GROUP BY 的时间格式
|
||||
*
|
||||
* @param deptId 部门编号
|
||||
* @return 用户编号数组
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return SQL 查询 GROUP BY 的时间格式
|
||||
*/
|
||||
public List<Long> getUserIds(Long deptId) {
|
||||
// 1. 获得部门列表
|
||||
List<Long> deptIds = convertList(deptApi.getChildDeptList(deptId), DeptRespDTO::getId);
|
||||
deptIds.add(deptId);
|
||||
// 2. 获得用户编号
|
||||
return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId);
|
||||
private String getSqlDateFormat(LocalDateTime startTime, LocalDateTime endTime) {
|
||||
return queryByMonth(startTime, endTime) ? SQL_DATE_FORMAT_BY_MONTH : SQL_DATE_FORMAT_BY_DAY;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,115 +2,240 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsCustomerMapper">
|
||||
|
||||
|
||||
<select id="selectCustomerCountGroupbyDate"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerCountVO">
|
||||
<select id="selectCustomerCreateCountGroupbyDate"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerSummaryByDateRespVO">
|
||||
SELECT
|
||||
DATE_FORMAT( create_time, #{sqlDateFormat,javaType=java.lang.String} ) AS category,
|
||||
count(*) AS count
|
||||
DATE_FORMAT( create_time, #{sqlDateFormat} ) AS time,
|
||||
count(*) AS customerCreateCount
|
||||
FROM crm_customer
|
||||
WHERE deleted = 0
|
||||
AND owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY time
|
||||
</select>
|
||||
|
||||
<select id="selectCustomerDealCountGroupbyDate"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerSummaryByDateRespVO">
|
||||
SELECT
|
||||
DATE_FORMAT( b.order_date, #{sqlDateFormat} ) AS time,
|
||||
count( DISTINCT a.id ) AS customerDealCount
|
||||
FROM crm_customer AS a
|
||||
LEFT JOIN crm_contract AS b ON b.customer_id = a.id
|
||||
WHERE a.deleted = 0 AND b.deleted = 0
|
||||
AND b.audit_status = 20
|
||||
AND a.owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND b.create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY time
|
||||
</select>
|
||||
|
||||
<select id="selectCustomerCreateCountGroupbyUser"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerSummaryByUserRespVO">
|
||||
SELECT owner_user_id, COUNT(1) AS customer_create_count
|
||||
FROM crm_customer
|
||||
WHERE deleted = 0
|
||||
AND owner_user_id in
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY owner_user_id
|
||||
</select>
|
||||
|
||||
<select id="selectCustomerDealCountGroupbyUser"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerSummaryByUserRespVO">
|
||||
SELECT a.owner_user_id, count( DISTINCT a.id ) AS customer_deal_count
|
||||
FROM crm_customer AS a
|
||||
LEFT JOIN crm_contract AS b ON b.customer_id = a.id
|
||||
WHERE a.deleted = 0 AND b.deleted = 0
|
||||
AND b.audit_status = 20
|
||||
AND a.owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND b.create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY a.owner_user_id
|
||||
</select>
|
||||
|
||||
<select id="selectContractPriceGroupbyUser"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerSummaryByUserRespVO">
|
||||
SELECT owner_user_id, IFNULL(SUM(total_price), 0) AS contract_price
|
||||
FROM crm_contract
|
||||
WHERE deleted = 0
|
||||
AND audit_status = 20
|
||||
AND owner_user_id in
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND order_date BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY owner_user_id
|
||||
</select>
|
||||
|
||||
|
||||
<select id="selectReceivablePriceGroupbyUser"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerSummaryByUserRespVO">
|
||||
SELECT owner_user_id,
|
||||
IFNULL(SUM(price), 0) AS receivable_price
|
||||
FROM crm_receivable
|
||||
WHERE deleted = 0
|
||||
AND audit_status = 20
|
||||
AND owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND return_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY owner_user_id
|
||||
</select>
|
||||
|
||||
<select id="selectFollowupRecordCountGroupbyDate"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsFollowupSummaryByDateRespVO">
|
||||
SELECT DATE_FORMAT( create_time, #{sqlDateFormat} ) AS time,
|
||||
count(*) AS followup_record_count
|
||||
FROM crm_follow_up_record
|
||||
WHERE creator IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
AND biz_type = #{bizType}
|
||||
GROUP BY time
|
||||
</select>
|
||||
|
||||
<select id="selectFollowupCustomerCountGroupbyDate"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsFollowupSummaryByDateRespVO">
|
||||
SELECT
|
||||
DATE_FORMAT( create_time, #{sqlDateFormat} ) AS time,
|
||||
count(DISTINCT biz_id) AS followup_customer_count
|
||||
FROM crm_follow_up_record
|
||||
WHERE creator IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
AND biz_type = #{bizType}
|
||||
GROUP BY time
|
||||
</select>
|
||||
|
||||
<select id="selectFollowupRecordCountGroupbyUser"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsFollowupSummaryByUserRespVO">
|
||||
SELECT creator as owner_user_id,
|
||||
count(*) AS followup_record_count
|
||||
FROM crm_follow_up_record
|
||||
WHERE creator IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
AND biz_type = #{bizType}
|
||||
GROUP BY creator
|
||||
</select>
|
||||
|
||||
<select id="selectFollowupCustomerCountGroupbyUser"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsFollowupSummaryByUserRespVO">
|
||||
SELECT creator as owner_user_id,
|
||||
count(DISTINCT biz_id) AS followup_customer_count
|
||||
FROM crm_follow_up_record
|
||||
WHERE creator IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
AND biz_type = #{bizType}
|
||||
GROUP BY creator
|
||||
</select>
|
||||
|
||||
<select id="selectFollowupRecordCountGroupbyType"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsFollowupSummaryByTypeRespVO">
|
||||
SELECT
|
||||
type AS followupType,
|
||||
count(*) AS followup_record_count
|
||||
FROM crm_follow_up_record
|
||||
WHERE creator IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
AND biz_type = #{bizType}
|
||||
GROUP BY followupType
|
||||
</select>
|
||||
|
||||
<select id="selectContractSummary"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerContractSummaryRespVO">
|
||||
SELECT
|
||||
a.`name` AS customer_name,
|
||||
b.`name` AS contract_name,
|
||||
b.total_price,
|
||||
IFNULL( c.price, 0 ) AS receivable_price,
|
||||
a.industry_id,
|
||||
a.source,
|
||||
a.owner_user_id,
|
||||
a.creator AS creator_user_id,
|
||||
a.create_time,
|
||||
b.order_date
|
||||
FROM
|
||||
crm_customer
|
||||
WHERE
|
||||
deleted = 0
|
||||
AND owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY category
|
||||
crm_customer AS a
|
||||
INNER JOIN crm_contract AS b ON a.id = b.customer_id
|
||||
LEFT JOIN crm_receivable AS c ON b.id = c.contract_id
|
||||
WHERE a.deleted = 0 AND b.deleted = 0 AND c.deleted = 0
|
||||
AND b.audit_status = 20
|
||||
AND a.owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND b.create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
</select>
|
||||
|
||||
<select id="selectDealCustomerCountGroupbyDate"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerCountVO">
|
||||
<select id="selectCustomerDealCycleGroupbyDate"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerDealCycleByDateRespVO">
|
||||
SELECT
|
||||
DATE_FORMAT( b.order_date, #{sqlDateFormat,javaType=java.lang.String} ) AS category,
|
||||
count( DISTINCT a.id ) AS count
|
||||
FROM
|
||||
crm_customer AS a
|
||||
LEFT JOIN crm_contract AS b ON b.customer_id = a.id
|
||||
WHERE
|
||||
a.deleted = 0 AND b.deleted = 0
|
||||
AND b.audit_status = 20
|
||||
AND a.owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND b.create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY category
|
||||
DATE_FORMAT( b.order_date, #{sqlDateFormat} ) AS time,
|
||||
IFNULL( TRUNCATE ( AVG( TIMESTAMPDIFF( DAY, a.create_time, b.order_date )), 1 ), 0 ) AS customer_deal_cycle
|
||||
FROM crm_customer AS a
|
||||
LEFT JOIN crm_contract AS b ON b.customer_id = a.id
|
||||
WHERE a.deleted = 0 AND b.deleted = 0
|
||||
AND b.audit_status = 20
|
||||
AND a.owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND b.create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY time
|
||||
</select>
|
||||
|
||||
<select id="selectRecordCountGroupbyDate"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerCountVO">
|
||||
<select id="selectCustomerDealCycleGroupbyUser"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerDealCycleByUserRespVO">
|
||||
SELECT
|
||||
DATE_FORMAT( create_time, #{sqlDateFormat,javaType=java.lang.String} ) AS category,
|
||||
count(*) AS count
|
||||
FROM
|
||||
crm_follow_up_record
|
||||
WHERE
|
||||
creator IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
AND biz_type = #{bizType,javaType=java.lang.Integer}
|
||||
GROUP BY category
|
||||
</select>
|
||||
|
||||
<select id="selectDistinctRecordCountGroupbyDate"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerCountVO">
|
||||
SELECT
|
||||
DATE_FORMAT( create_time, #{sqlDateFormat,javaType=java.lang.String} ) AS category,
|
||||
count(DISTINCT biz_id) AS count
|
||||
FROM
|
||||
crm_follow_up_record
|
||||
WHERE
|
||||
creator IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
AND biz_type = #{bizType,javaType=java.lang.Integer}
|
||||
GROUP BY category
|
||||
</select>
|
||||
|
||||
<select id="selectRecordCountGroupbyType"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerCountVO">
|
||||
SELECT
|
||||
type AS category,
|
||||
count(*) AS count
|
||||
FROM crm_follow_up_record
|
||||
WHERE
|
||||
creator IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
AND biz_type = #{bizType,javaType=java.lang.Integer}
|
||||
GROUP BY category
|
||||
</select>
|
||||
|
||||
<select id="selectCustomerCycleGroupbyDate"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerCountVO">
|
||||
SELECT
|
||||
DATE_FORMAT( b.order_date, #{sqlDateFormat,javaType=java.lang.String} ) AS category,
|
||||
IFNULL( TRUNCATE ( AVG( TIMESTAMPDIFF( DAY, a.create_time, b.order_date )), 1 ), 0 ) AS cycle
|
||||
FROM crm_customer AS a
|
||||
LEFT JOIN crm_contract AS b ON b.customer_id = a.id
|
||||
WHERE
|
||||
a.deleted = 0 AND b.deleted = 0
|
||||
AND b.audit_status = 20
|
||||
AND a.owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND b.create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY category
|
||||
a.owner_user_id,
|
||||
IFNULL( TRUNCATE ( AVG( TIMESTAMPDIFF( DAY, a.create_time, b.order_date )), 1 ), 0 ) AS customer_deal_cycle
|
||||
FROM crm_customer AS a
|
||||
LEFT JOIN crm_contract AS b ON b.customer_id = a.id
|
||||
WHERE a.deleted = 0 AND b.deleted = 0
|
||||
AND b.audit_status = 20
|
||||
AND a.owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND b.create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY a.owner_user_id
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
Loading…
Reference in New Issue
Block a user