diff --git a/pom.xml b/pom.xml
index 3a66524bc..9cf34eb37 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,12 +16,12 @@
yudao-module-system
yudao-module-infra
-
+ yudao-module-bpm
-
+ yudao-module-crm
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerByUserBaseRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerByUserBaseRespVO.java
index 340e93066..41fa9152e 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerByUserBaseRespVO.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerByUserBaseRespVO.java
@@ -5,12 +5,14 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
- * 用户客户统计响应 Base VO
+ * 用户客户统计响应 Base Response VO
+ *
+ * 目的:可以统一拼接子 VO 的 ownerUserId、ownerUserName 属性
*/
@Data
public class CrmStatisticsCustomerByUserBaseRespVO {
- @Schema(description = "负责人ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@JsonIgnore
private Long ownerUserId;
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerContractSummaryRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerContractSummaryRespVO.java
index 019309f8e..ec1d27303 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerContractSummaryRespVO.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerContractSummaryRespVO.java
@@ -5,13 +5,13 @@ 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.*;
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
@Schema(description = "管理后台 - CRM 客户转化率分析 VO")
@Data
@@ -43,14 +43,14 @@ public class CrmStatisticsCustomerContractSummaryRespVO {
@Schema(description = "客户来源", requiredMode = Schema.RequiredMode.REQUIRED, example = "外呼")
private String sourceName;
- @Schema(description = "负责人ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @Schema(description = "负责人编号", 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")
+ @Schema(description = "创建人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@JsonIgnore
private String creatorUserId;
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerReqVO.java
index a7aaa4da5..c5d5acbc3 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerReqVO.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerReqVO.java
@@ -12,7 +12,7 @@ import java.util.List;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-@Schema(description = "管理后台 - CRM 数据统计 员工客户分析 Request VO")
+@Schema(description = "管理后台 - CRM 数据统计的员工客户分析 Request VO")
@Data
public class CrmStatisticsCustomerReqVO {
@@ -39,12 +39,16 @@ public class CrmStatisticsCustomerReqVO {
@NotEmpty(message = "时间范围不能为空")
private LocalDateTime[] times;
+ // TODO @dhb52:这个时间间隔,建议前端传递;例如说:字段叫 interval,枚举有天、周、月、季度、年。因为一般分析类的系统,都是交给用户选择筛选时间间隔,而我们这里是默认根据日期选项,默认对应的 interval 而已
+ // 然后实现上,可以在 common 包的 enums 加个 DateIntervalEnum,里面一个是 interval 字段,枚举过去,然后有个 pattern 字段,用于格式化时间格式;
+ // 这样的话,可以通过 interval 获取到 pattern,然后前端就可以根据 pattern 格式化时间,计算还是交给数据库
/**
* group by DATE_FORMAT(field, #{dateFormat})
*/
@Schema(description = "Group By 日期格式", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "%Y%m")
private String sqlDateFormat;
+ // TODO @dhb52:这个字段,目前是不是没啥用呀?
/**
* 数据类型 {@link CrmBizTypeEnum}
*/
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsCustomerMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsCustomerMapper.java
index 6bababa26..19bd76fc3 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsCustomerMapper.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsCustomerMapper.java
@@ -13,17 +13,18 @@ import java.util.List;
@Mapper
public interface CrmStatisticsCustomerMapper {
- List selectCustomerCreateCountGroupbyDate(CrmStatisticsCustomerReqVO reqVO);
+ // TODO @dhb52:拼写,GroupBy。一般 idea 如果出现绿色的警告,可能是单词拼写错误,建议是要修改的哈;
+ List selectCustomerCreateCountGroupbyDate(CrmStatisticsCustomerReqVO reqVO); // 已经 review
- List selectCustomerDealCountGroupbyDate(CrmStatisticsCustomerReqVO reqVO);
+ List selectCustomerDealCountGroupbyDate(CrmStatisticsCustomerReqVO reqVO); // 已经 review
- List selectCustomerCreateCountGroupbyUser(CrmStatisticsCustomerReqVO reqVO);
+ List selectCustomerCreateCountGroupbyUser(CrmStatisticsCustomerReqVO reqVO); // 已经 review
- List selectCustomerDealCountGroupbyUser(CrmStatisticsCustomerReqVO crmStatisticsCustomerReqVO);
+ List selectCustomerDealCountGroupbyUser(CrmStatisticsCustomerReqVO crmStatisticsCustomerReqVO); // 已经 review
- List selectContractPriceGroupbyUser(CrmStatisticsCustomerReqVO crmStatisticsCustomerReqVO);
+ List selectContractPriceGroupbyUser(CrmStatisticsCustomerReqVO crmStatisticsCustomerReqVO); // 已经 review
- List selectReceivablePriceGroupbyUser(CrmStatisticsCustomerReqVO crmStatisticsCustomerReqVO);
+ List selectReceivablePriceGroupbyUser(CrmStatisticsCustomerReqVO crmStatisticsCustomerReqVO); // 已经 review
List selectFollowupRecordCountGroupbyDate(CrmStatisticsCustomerReqVO reqVO);
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsCustomerServiceImpl.java
index 6b664dce5..c9654a68e 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsCustomerServiceImpl.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsCustomerServiceImpl.java
@@ -55,7 +55,6 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
@Resource
private DictDataApi dictDataApi;
-
@Override
public List getCustomerSummaryByDate(CrmStatisticsCustomerReqVO reqVO) {
// 1. 获得用户编号数组
@@ -66,14 +65,17 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
reqVO.setUserIds(userIds);
// 2. 获取分项统计数据
+ // TODO @dhb52:如果是 list 变量,要么 List 要么 s 后缀
reqVO.setSqlDateFormat(getSqlDateFormat(reqVO.getTimes()[0], reqVO.getTimes()[1]));
final List customerCreateCount = customerMapper.selectCustomerCreateCountGroupbyDate(reqVO);
final List customerDealCount = customerMapper.selectCustomerDealCountGroupbyDate(reqVO);
// 3. 获取时间序列
+ // TODO @dhb52:3 和 4 其实做的是一类事情,所以可以考虑 3.1 获取时间序列、3.2 合并统计数据 这样注释;然后中间就不空行了;就是说,一般空行的目的,是让逻辑分片,看着整体性更好,但是不能让逻辑感觉碎碎的;
final List times = generateTimeSeries(reqVO.getTimes()[0], reqVO.getTimes()[1]);
// 4. 合并统计数据
+ // TODO @dhb52:这个是不是要 add 到 respVoList 里?或者还可以 convertList(times, time -> new CrmStatisticsCustomerDealCycleByDateRespVO()...)
List respVoList = new ArrayList<>(times.size());
final Map customerCreateCountMap = convertMap(customerCreateCount,
CrmStatisticsCustomerSummaryByDateRespVO::getTime,
@@ -86,7 +88,6 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
.setCustomerCreateCount(customerCreateCountMap.getOrDefault(time, 0))
.setCustomerDealCount(customerDealCountMap.getOrDefault(time, 0))
));
-
return respVoList;
}
@@ -131,7 +132,6 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
// 4. 拼接用户信息
appendUserInfo(respVoList);
-
return respVoList;
}
@@ -202,7 +202,6 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
// 4. 拼接用户信息
appendUserInfo(respVoList);
-
return respVoList;
}
@@ -290,7 +289,6 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
new CrmStatisticsCustomerDealCycleByDateRespVO().setTime(time)
.setCustomerDealCycle(customerDealCycleMap.getOrDefault(time, 0D))
));
-
return respVoList;
}
@@ -337,9 +335,8 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
*/
private void appendUserInfo(List respVoList) {
Map userMap = adminUserApi.getUserMap(convertSet(respVoList,
- CrmStatisticsCustomerByUserBaseRespVO::getOwnerUserId));
- respVoList.forEach(vo -> MapUtils.findAndThen(userMap,
- vo.getOwnerUserId(), user -> vo.setOwnerUserName(user.getNickname())));
+ CrmStatisticsCustomerByUserBaseRespVO::getOwnerUserId));
+ respVoList.forEach(vo -> MapUtils.findAndThen(userMap, vo.getOwnerUserId(), user -> vo.setOwnerUserName(user.getNickname())));
}
/**
@@ -349,16 +346,17 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
* @return 用户编号数组
*/
private List getUserIds(CrmStatisticsCustomerReqVO reqVO) {
+ // 情况一:选中某个用户
if (ObjUtil.isNotNull(reqVO.getUserId())) {
return List.of(reqVO.getUserId());
- } else {
- // 1. 获得部门列表
- final Long deptId = reqVO.getDeptId();
- List deptIds = convertList(deptApi.getChildDeptList(deptId), DeptRespDTO::getId);
- deptIds.add(deptId);
- // 2. 获得用户编号
- return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId);
}
+ // 情况二:选中某个部门
+ // 2.1 获得部门列表
+ final Long deptId = reqVO.getDeptId();
+ List deptIds = convertList(deptApi.getChildDeptList(deptId), DeptRespDTO::getId);
+ deptIds.add(deptId);
+ // 2.2 获得用户编号
+ return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId);
}
@@ -380,6 +378,7 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
* @param endTime 结束时间
* @return 时间序列
*/
+ // TODO @dhb52:可以抽象到 DateUtils 里,开始时间、结束时间,事件间隔,然后返回这个哈;
private List generateTimeSeries(LocalDateTime startTime, LocalDateTime endTime) {
boolean byMonth = queryByMonth(startTime, endTime);
List times = CollUtil.newArrayList();
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsCustomerMapper.xml b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsCustomerMapper.xml
index 3fd52f3e7..fce255651 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsCustomerMapper.xml
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsCustomerMapper.xml
@@ -2,11 +2,14 @@
+
+
@@ -21,6 +25,8 @@
+
+
+
+