CRM:重构【客户画像】,从【客户统计】拆分出去先~
parent
3b379d8cc0
commit
924580f4a2
@ -0,0 +1,61 @@
|
|||||||
|
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.CrmStatisticsCustomerReqVO;
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerAreaRespVO;
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerIndustryRespVO;
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerLevelRespVO;
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerSourceRespVO;
|
||||||
|
import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsPortraitService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
@Tag(name = "管理后台 - CRM 客户画像")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/crm/statistics-portrait")
|
||||||
|
@Validated
|
||||||
|
public class CrmStatisticsPortraitController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CrmStatisticsPortraitService statisticsPortraitService;
|
||||||
|
|
||||||
|
@GetMapping("/get-customer-area-summary")
|
||||||
|
@Operation(summary = "获取客户地区统计数据", description = "用于【城市分布分析】页面")
|
||||||
|
@PreAuthorize("@ss.hasPermission('crm:statistics-portrait:query')")
|
||||||
|
public CommonResult<List<CrmStatisticCustomerAreaRespVO>> getCustomerAreaSummary(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||||
|
return success(statisticsPortraitService.getCustomerArea(reqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get-customer-industry-summary")
|
||||||
|
@Operation(summary = "获取客户行业统计数据")
|
||||||
|
@PreAuthorize("@ss.hasPermission('crm:statistics-portrait:query')")
|
||||||
|
public CommonResult<List<CrmStatisticCustomerIndustryRespVO>> getCustomerIndustry(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||||
|
return success(statisticsPortraitService.getCustomerIndustry(reqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get-customer-level-summary")
|
||||||
|
@Operation(summary = "获取客户级别统计数据")
|
||||||
|
@PreAuthorize("@ss.hasPermission('crm:statistics-portrait:query')")
|
||||||
|
public CommonResult<List<CrmStatisticCustomerLevelRespVO>> getCustomerLevel(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||||
|
return success(statisticsPortraitService.getCustomerLevel(reqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get-customer-source-summary")
|
||||||
|
@Operation(summary = "获取客户来源统计数据")
|
||||||
|
@PreAuthorize("@ss.hasPermission('crm:statistics-portrait:query')")
|
||||||
|
public CommonResult<List<CrmStatisticCustomerSourceRespVO>> getCustomerSource(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||||
|
return success(statisticsPortraitService.getCustomerSource(reqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
2
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/analyze/CrmStatisticCustomerAreaRespVO.java → yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerAreaRespVO.java
2
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/analyze/CrmStatisticCustomerAreaRespVO.java → yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerAreaRespVO.java
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.analyze;
|
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
2
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/analyze/CrmStatisticCustomerIndustryRespVO.java → yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerIndustryRespVO.java
2
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/analyze/CrmStatisticCustomerIndustryRespVO.java → yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerIndustryRespVO.java
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.analyze;
|
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
2
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/analyze/CrmStatisticCustomerLevelRespVO.java → yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerLevelRespVO.java
2
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/analyze/CrmStatisticCustomerLevelRespVO.java → yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerLevelRespVO.java
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.analyze;
|
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
2
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/analyze/CrmStatisticCustomerSourceRespVO.java → yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerSourceRespVO.java
2
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/analyze/CrmStatisticCustomerSourceRespVO.java → yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerSourceRespVO.java
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.analyze;
|
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.dal.mysql.statistics;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.*;
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerAreaRespVO;
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerIndustryRespVO;
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerLevelRespVO;
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerSourceRespVO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CRM 数据画像 Mapper
|
||||||
|
*
|
||||||
|
* @author dhb52
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface CrmStatisticsPortraitMapper {
|
||||||
|
|
||||||
|
List<CrmStatisticCustomerIndustryRespVO> selectCustomerIndustryListGroupbyIndustryId(CrmStatisticsCustomerReqVO reqVO);
|
||||||
|
|
||||||
|
List<CrmStatisticCustomerSourceRespVO> selectCustomerSourceListGroupbySource(CrmStatisticsCustomerReqVO reqVO);
|
||||||
|
|
||||||
|
List<CrmStatisticCustomerLevelRespVO> selectCustomerLevelListGroupbyLevel(CrmStatisticsCustomerReqVO reqVO);
|
||||||
|
|
||||||
|
List<CrmStatisticCustomerAreaRespVO> selectSummaryListByAreaId(CrmStatisticsCustomerReqVO reqVO);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.service.statistics;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerReqVO;
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerAreaRespVO;
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerIndustryRespVO;
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerLevelRespVO;
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerSourceRespVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CRM 客户画像 Service 接口
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
public interface CrmStatisticsPortraitService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取客户地区统计数据
|
||||||
|
*
|
||||||
|
* @param reqVO 请求参数
|
||||||
|
* @return 统计数据
|
||||||
|
*/
|
||||||
|
List<CrmStatisticCustomerAreaRespVO> getCustomerArea(CrmStatisticsCustomerReqVO reqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取客户行业统计数据
|
||||||
|
*
|
||||||
|
* @param reqVO 请求参数
|
||||||
|
* @return 统计数据
|
||||||
|
*/
|
||||||
|
List<CrmStatisticCustomerIndustryRespVO> getCustomerIndustry(CrmStatisticsCustomerReqVO reqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取客户级别统计数据
|
||||||
|
*
|
||||||
|
* @param reqVO 请求参数
|
||||||
|
* @return 统计数据
|
||||||
|
*/
|
||||||
|
List<CrmStatisticCustomerLevelRespVO> getCustomerLevel(CrmStatisticsCustomerReqVO reqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取客户来源统计数据
|
||||||
|
*
|
||||||
|
* @param reqVO 请求参数
|
||||||
|
* @return 统计数据
|
||||||
|
*/
|
||||||
|
List<CrmStatisticCustomerSourceRespVO> getCustomerSource(CrmStatisticsCustomerReqVO reqVO);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!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.CrmStatisticsPortraitMapper">
|
||||||
|
|
||||||
|
<select id="selectCustomerIndustryListGroupbyIndustryId"
|
||||||
|
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerIndustryRespVO">
|
||||||
|
SELECT
|
||||||
|
industry_id,
|
||||||
|
COUNT(*) AS customerCount,
|
||||||
|
SUM(deal_status) AS dealCount,
|
||||||
|
ROUND(COUNT(*) / (SELECT COUNT(*) FROM crm_customer WHERE deleted = 0) * 100, 2) AS industryPortion,
|
||||||
|
ROUND(SUM(deal_status) / NULLIF(COUNT(*), 0) * 100, 2) AS dealPortion
|
||||||
|
FROM
|
||||||
|
crm_customer
|
||||||
|
WHERE
|
||||||
|
deleted = 0 AND industry_id IS NOT NULL
|
||||||
|
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
|
||||||
|
industry_id;
|
||||||
|
</select>
|
||||||
|
<select id="selectCustomerSourceListGroupbySource"
|
||||||
|
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerSourceRespVO">
|
||||||
|
SELECT
|
||||||
|
source,
|
||||||
|
COUNT(*) AS customerCount,
|
||||||
|
SUM(deal_status) AS dealCount,
|
||||||
|
ROUND(COUNT(*) / (SELECT COUNT(*) FROM crm_customer WHERE deleted = 0) * 100, 2) AS sourcePortion,
|
||||||
|
ROUND(SUM(deal_status) / NULLIF(COUNT(*), 0) * 100, 2) AS dealPortion
|
||||||
|
FROM
|
||||||
|
crm_customer
|
||||||
|
WHERE
|
||||||
|
deleted = 0 AND source IS NOT NULL
|
||||||
|
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
|
||||||
|
source;
|
||||||
|
</select>
|
||||||
|
<select id="selectCustomerLevelListGroupbyLevel"
|
||||||
|
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerLevelRespVO">
|
||||||
|
SELECT
|
||||||
|
level,
|
||||||
|
COUNT(*) AS customerCount,
|
||||||
|
SUM(deal_status) AS dealCount,
|
||||||
|
ROUND(COUNT(*) / (SELECT COUNT(*) FROM crm_customer WHERE deleted = 0) * 100, 2) AS levelPortion,
|
||||||
|
ROUND(SUM(deal_status) / NULLIF(COUNT(*), 0) * 100, 2) AS dealPortion
|
||||||
|
FROM
|
||||||
|
crm_customer
|
||||||
|
WHERE
|
||||||
|
deleted = 0 AND level IS NOT NULL
|
||||||
|
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
|
||||||
|
level;
|
||||||
|
</select>
|
||||||
|
<select id="selectSummaryListByAreaId"
|
||||||
|
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerAreaRespVO">
|
||||||
|
SELECT
|
||||||
|
area_id,
|
||||||
|
COUNT(*) AS customerCount,
|
||||||
|
SUM(deal_status) AS dealCount,
|
||||||
|
ROUND(COUNT(*) / (SELECT COUNT(*) FROM crm_customer WHERE deleted = 0) * 100, 2) AS areaPortion,
|
||||||
|
ROUND(SUM(deal_status) / NULLIF(COUNT(*), 0) * 100, 2) AS dealPortion
|
||||||
|
FROM
|
||||||
|
crm_customer
|
||||||
|
WHERE
|
||||||
|
deleted = 0 AND area_id IS NOT NULL
|
||||||
|
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
|
||||||
|
area_id;
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
Loading…
Reference in New Issue