mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-02-02 03:34:58 +08:00
feat: [CRM-客户分析]增加[时间间隔]选项
This commit is contained in:
parent
ee2be79987
commit
4ac28603b8
@ -0,0 +1,48 @@
|
||||
package cn.iocoder.yudao.framework.common.enums;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 时间间隔类型枚举
|
||||
*
|
||||
* @author dhb52
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DateIntervalEnum implements IntArrayValuable {
|
||||
|
||||
TODAY(1, "今天"),
|
||||
YESTERDAY(2, "昨天"),
|
||||
THIS_WEEK(3, "本周"),
|
||||
LAST_WEEK(4, "上周"),
|
||||
THIS_MONTH(5, "本月"),
|
||||
LAST_MONTH(6, "上月"),
|
||||
THIS_QUARTER(7, "本季度"),
|
||||
LAST_QUARTER(8, "上季度"),
|
||||
THIS_YEAR(9, "本年"),
|
||||
LAST_YEAR(10, "去年"),
|
||||
CUSTOMER(11, "自定义"),
|
||||
;
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DateIntervalEnum::getType).toArray();
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer type;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
@ -103,4 +103,7 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode FOLLOW_UP_RECORD_NOT_EXISTS = new ErrorCode(1_020_013_000, "跟进记录不存在");
|
||||
ErrorCode FOLLOW_UP_RECORD_DELETE_DENIED = new ErrorCode(1_020_013_001, "删除跟进记录失败,原因:没有权限");
|
||||
|
||||
// ========== 数据统计 1_020_014_000 ==========
|
||||
ErrorCode STATISTICS_CUSTOMER_TIMES_NOT_SET = new ErrorCode(1_020_014_000, "自定义时间间隔,必须输入时间区间");
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.DateIntervalEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
@ -27,22 +28,26 @@ public class CrmStatisticsCustomerReqVO {
|
||||
|
||||
/**
|
||||
* userIds 目前不用前端传递,目前是方便后端通过 deptId 读取编号后,设置回来
|
||||
* <p>
|
||||
* 后续,可能会支持选择部分用户进行查询
|
||||
*/
|
||||
@Schema(description = "负责人用户 id 集合", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "2")
|
||||
private List<Long> userIds;
|
||||
|
||||
@Schema(description = "时间范围", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "时间间隔类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@InEnum(value = DateIntervalEnum.class, message = "时间间隔类型,必须是 {value}")
|
||||
private Integer intervalType;
|
||||
|
||||
/**
|
||||
* 前端如果选择自定义时间, 那么前端传递起始-终止时间, 如果选择其他时间间隔类型, 则由后台计算起始-终止时间
|
||||
* 并作为参数传递给Mapper
|
||||
*/
|
||||
@Schema(description = "时间范围", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@NotEmpty(message = "时间范围不能为空")
|
||||
private LocalDateTime[] times;
|
||||
|
||||
// TODO @dhb52:这个时间间隔,建议前端传递;例如说:字段叫 interval,枚举有天、周、月、季度、年。因为一般分析类的系统,都是交给用户选择筛选时间间隔,而我们这里是默认根据日期选项,默认对应的 interval 而已
|
||||
// 然后实现上,可以在 common 包的 enums 加个 DateIntervalEnum,里面一个是 interval 字段,枚举过去,然后有个 pattern 字段,用于格式化时间格式;
|
||||
// 这样的话,可以通过 interval 获取到 pattern,然后前端就可以根据 pattern 格式化时间,计算还是交给数据库
|
||||
/**
|
||||
* group by DATE_FORMAT(field, #{dateFormat})
|
||||
* 非前端传递, 由Service计算后传递给Mapper的参数
|
||||
*/
|
||||
@Schema(description = "Group By 日期格式", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "%Y%m")
|
||||
private String sqlDateFormat;
|
||||
|
@ -1,8 +1,11 @@
|
||||
package cn.iocoder.yudao.module.crm.service.statistics;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.DateIntervalEnum;
|
||||
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.*;
|
||||
@ -24,8 +27,10 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.*;
|
||||
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.STATISTICS_CUSTOMER_TIMES_NOT_SET;
|
||||
|
||||
/**
|
||||
* CRM 客户分析 Service 实现类
|
||||
@ -63,7 +68,7 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取分项统计数据
|
||||
reqVO.setSqlDateFormat(getSqlDateFormat(reqVO.getTimes()[0], reqVO.getTimes()[1]));
|
||||
initParams(reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByDateRespVO> customerCreateCountVoList = customerMapper.selectCustomerCreateCountGroupByDate(reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByDateRespVO> customerDealCountVoList = customerMapper.selectCustomerDealCountGroupByDate(reqVO);
|
||||
|
||||
@ -94,6 +99,7 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取分项统计数据
|
||||
initParams(reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByUserRespVO> customerCreateCount = customerMapper.selectCustomerCreateCountGroupByUser(reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByUserRespVO> customerDealCount = customerMapper.selectCustomerDealCountGroupByUser(reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByUserRespVO> contractPrice = customerMapper.selectContractPriceGroupByUser(reqVO);
|
||||
@ -139,7 +145,7 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取分项统计数据
|
||||
reqVO.setSqlDateFormat(getSqlDateFormat(reqVO.getTimes()[0], reqVO.getTimes()[1]));
|
||||
initParams(reqVO);
|
||||
List<CrmStatisticsFollowupSummaryByDateRespVO> followupRecordCount = customerMapper.selectFollowupRecordCountGroupByDate(reqVO);
|
||||
List<CrmStatisticsFollowupSummaryByDateRespVO> followupCustomerCount = customerMapper.selectFollowupCustomerCountGroupByDate(reqVO);
|
||||
|
||||
@ -170,6 +176,7 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取分项统计数据
|
||||
initParams(reqVO);
|
||||
List<CrmStatisticsFollowupSummaryByUserRespVO> followupRecordCount = customerMapper.selectFollowupRecordCountGroupByUser(reqVO);
|
||||
List<CrmStatisticsFollowupSummaryByUserRespVO> followupCustomerCount = customerMapper.selectFollowupCustomerCountGroupByUser(reqVO);
|
||||
|
||||
@ -204,6 +211,7 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获得排行数据
|
||||
initParams(reqVO);
|
||||
List<CrmStatisticsFollowupSummaryByTypeRespVO> respVoList = customerMapper.selectFollowupRecordCountGroupByType(reqVO);
|
||||
|
||||
// 3. 获取字典数据
|
||||
@ -227,6 +235,7 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取统计数据
|
||||
initParams(reqVO);
|
||||
List<CrmStatisticsCustomerContractSummaryRespVO> respVoList = customerMapper.selectContractSummary(reqVO);
|
||||
|
||||
// 3. 设置 创建人、负责人、行业、来源
|
||||
@ -261,7 +270,7 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取分项统计数据
|
||||
reqVO.setSqlDateFormat(getSqlDateFormat(reqVO.getTimes()[0], reqVO.getTimes()[1]));
|
||||
initParams(reqVO);
|
||||
List<CrmStatisticsCustomerDealCycleByDateRespVO> customerDealCycle = customerMapper.selectCustomerDealCycleGroupByDate(reqVO);
|
||||
|
||||
// 3. 合并统计数据
|
||||
@ -287,6 +296,7 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取分项统计数据
|
||||
initParams(reqVO);
|
||||
List<CrmStatisticsCustomerDealCycleByUserRespVO> customerDealCycle = customerMapper.selectCustomerDealCycleGroupByUser(reqVO);
|
||||
List<CrmStatisticsCustomerSummaryByUserRespVO> customerDealCount = customerMapper.selectCustomerDealCountGroupByUser(reqVO);
|
||||
|
||||
@ -363,7 +373,6 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
* @param endTime 结束时间
|
||||
* @return 时间序列
|
||||
*/
|
||||
// TODO @dhb52:可以抽象到 DateUtils 里,开始时间、结束时间,事件间隔,然后返回这个哈;
|
||||
private List<String> generateTimeSeries(LocalDateTime startTime, LocalDateTime endTime) {
|
||||
boolean byMonth = queryByMonth(startTime, endTime);
|
||||
List<String> times = CollUtil.newArrayList();
|
||||
@ -389,4 +398,62 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
return queryByMonth(startTime, endTime) ? SQL_DATE_FORMAT_BY_MONTH : SQL_DATE_FORMAT_BY_DAY;
|
||||
}
|
||||
|
||||
private void initParams(CrmStatisticsCustomerReqVO reqVO) {
|
||||
final Integer intervalType = reqVO.getIntervalType();
|
||||
|
||||
// 1. 自定义时间间隔,必须输入起始日期-结束日期
|
||||
if (DateIntervalEnum.CUSTOMER.getType().equals(intervalType)) {
|
||||
if (ObjUtil.isEmpty(reqVO.getTimes()) || reqVO.getTimes().length != 2) {
|
||||
throw exception(STATISTICS_CUSTOMER_TIMES_NOT_SET);
|
||||
}
|
||||
// 设置 mapper sqlDateFormat 参数
|
||||
reqVO.setSqlDateFormat(getSqlDateFormat(reqVO.getTimes()[0], reqVO.getTimes()[1]));
|
||||
// 自定义日期无需计算日期参数
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 根据时间区间类型计算时间段区间日期
|
||||
DateTime beginDate = null;
|
||||
DateTime endDate = null;
|
||||
if (DateIntervalEnum.TODAY.getType().equals(intervalType)) {
|
||||
beginDate = DateUtil.beginOfDay(DateUtil.date());
|
||||
endDate = DateUtil.endOfDay(DateUtil.date());
|
||||
} else if (DateIntervalEnum.YESTERDAY.getType().equals(intervalType)) {
|
||||
beginDate = DateUtil.offsetDay(DateUtil.date(), -1);
|
||||
endDate = DateUtil.offsetDay(DateUtil.date(), -1);
|
||||
} else if (DateIntervalEnum.THIS_WEEK.getType().equals(intervalType)) {
|
||||
beginDate = DateUtil.beginOfWeek(DateUtil.date());
|
||||
endDate = DateUtil.endOfWeek(DateUtil.date());
|
||||
} else if (DateIntervalEnum.LAST_WEEK.getType().equals(intervalType)) {
|
||||
beginDate = DateUtil.beginOfWeek(DateUtil.offsetWeek(DateUtil.date(), -1));
|
||||
endDate = DateUtil.endOfWeek(DateUtil.offsetWeek(DateUtil.date(), -1));
|
||||
} else if (DateIntervalEnum.THIS_MONTH.getType().equals(intervalType)) {
|
||||
beginDate = DateUtil.beginOfMonth(DateUtil.date());
|
||||
endDate = DateUtil.endOfMonth(DateUtil.date());
|
||||
} else if (DateIntervalEnum.LAST_MONTH.getType().equals(intervalType)) {
|
||||
beginDate = DateUtil.beginOfMonth(DateUtil.offsetMonth(DateUtil.date(), -1));
|
||||
endDate = DateUtil.endOfMonth(DateUtil.offsetMonth(DateUtil.date(), -1));
|
||||
} else if (DateIntervalEnum.THIS_QUARTER.getType().equals(intervalType)) {
|
||||
beginDate = DateUtil.beginOfQuarter(DateUtil.date());
|
||||
endDate = DateUtil.endOfQuarter(DateUtil.date());
|
||||
} else if (DateIntervalEnum.LAST_QUARTER.getType().equals(intervalType)) {
|
||||
beginDate = DateUtil.beginOfQuarter(DateUtil.offsetMonth(DateUtil.date(), -3));
|
||||
endDate = DateUtil.endOfQuarter(DateUtil.offsetMonth(DateUtil.date(), -3));
|
||||
} else if (DateIntervalEnum.THIS_YEAR.getType().equals(intervalType)) {
|
||||
beginDate = DateUtil.beginOfYear(DateUtil.date());
|
||||
endDate = DateUtil.endOfYear(DateUtil.date());
|
||||
} else if (DateIntervalEnum.LAST_YEAR.getType().equals(intervalType)) {
|
||||
beginDate = DateUtil.beginOfYear(DateUtil.offsetMonth(DateUtil.date(), -12));
|
||||
endDate = DateUtil.endOfYear(DateUtil.offsetMonth(DateUtil.date(), -12));
|
||||
}
|
||||
|
||||
// 3. 计算开始、结束日期时间,并设置reqVo
|
||||
LocalDateTime[] times = new LocalDateTime[2];
|
||||
times[0] = LocalDateTimeUtil.beginOfDay(LocalDateTimeUtil.of(beginDate));
|
||||
times[1] = LocalDateTimeUtil.endOfDay(LocalDateTimeUtil.of(endDate));
|
||||
// 3.1 设置 mapper 时间区间 参数
|
||||
reqVO.setTimes(times);
|
||||
// 3.2 设置 mapper sqlDateFormat 参数
|
||||
reqVO.setSqlDateFormat(getSqlDateFormat(times[0], times[1]));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user