修改成单数据和进粉数据不正确的问题

This commit is contained in:
MerCry 2026-03-13 22:35:14 +08:00
parent f7ecda456e
commit ba3f96b2d3
4 changed files with 383 additions and 129 deletions

View File

@ -492,7 +492,7 @@ import java.util.concurrent.atomic.AtomicInteger;
stats.setStudentDailyOrderCount(stats.getStudentDailyOrderCount() + 1); stats.setStudentDailyOrderCount(stats.getStudentDailyOrderCount() + 1);
} }
} }
} else { } else if(data.getAddDate().compareTo(targetDate) == 0){
stats.setManagerAcceptCount(stats.getManagerAcceptCount() + 1); stats.setManagerAcceptCount(stats.getManagerAcceptCount() + 1);
} }
} }
@ -542,6 +542,9 @@ import java.util.concurrent.atomic.AtomicInteger;
GROUP_ATTR_MAP.put("AD组", "tag_group17"); GROUP_ATTR_MAP.put("AD组", "tag_group17");
GROUP_ATTR_MAP.put("AE组", "tag_group18"); GROUP_ATTR_MAP.put("AE组", "tag_group18");
} }
private static final String UNGROUPED_NAME = "未分组";
/** /**
* 字段反射缓存 * 字段反射缓存
*/ */
@ -563,9 +566,11 @@ import java.util.concurrent.atomic.AtomicInteger;
} }
private boolean matchesSource(CustomerExportData data) { private boolean matchesSource(CustomerExportData data) {
if(data.getSource() == null) {
return true;
}
// 条件: 排除"由管理员XXX分配" // 条件: 排除"由管理员XXX分配"
if (data.getSource() != null && if (data.getSource().contains("管理员") &&
data.getSource().contains("管理员") &&
data.getSource().contains("分配")) { data.getSource().contains("分配")) {
return false; return false;
} }
@ -657,13 +662,16 @@ import java.util.concurrent.atomic.AtomicInteger;
} }
} }
private boolean matchOrderCompleted(CustomerExportData data,Date curDate) { /**
* 检查是否是成单状态
*/
private boolean isOrderCompleted(CustomerExportData data) {
String orderStatus = data.getTagGroup7(); // T列成交状态 String orderStatus = data.getTagGroup7(); // T列成交状态
// 校验成交状态 if (orderStatus == null || orderStatus.trim().isEmpty()) {
if (!orderStatus.equals("已成交及时单9元+") && !orderStatus.equals("已成交非及时单9元+")) {
return false; return false;
} }
return true; // 校验成交状态
return orderStatus.contains("已成交及时单9元+") || orderStatus.contains("已成交非及时单9元+");
} }
private boolean isTimelyOrder(CustomerExportData data) { private boolean isTimelyOrder(CustomerExportData data) {
@ -684,6 +692,8 @@ import java.util.concurrent.atomic.AtomicInteger;
* 处理单条数据记录累加到所有相关组的统计中 * 处理单条数据记录累加到所有相关组的统计中
*/ */
private void processDataRecord(CustomerExportData data, Date date, StatisticsAccumulator accumulator) { private void processDataRecord(CustomerExportData data, Date date, StatisticsAccumulator accumulator) {
boolean hasGroup = false;
// 遍历所有组 // 遍历所有组
for (Map.Entry<String, String> entry : GROUP_FIELD_MAP.entrySet()) { for (Map.Entry<String, String> entry : GROUP_FIELD_MAP.entrySet()) {
String groupName = entry.getKey(); String groupName = entry.getKey();
@ -697,12 +707,20 @@ import java.util.concurrent.atomic.AtomicInteger;
continue; continue;
} }
hasGroup = true;
// 获取该组的统计器 // 获取该组的统计器
StatisticsAccumulator.GroupStatistics stats = accumulator.getGroupStats(groupName); StatisticsAccumulator.GroupStatistics stats = accumulator.getGroupStats(groupName);
// 累加各项统计指标 // 累加各项统计指标
accumulateGroupStatistics(data, date, stats); accumulateGroupStatistics(data, date, stats);
} }
// 如果不属于任何组统计到"未分组"
if (!hasGroup) {
StatisticsAccumulator.GroupStatistics ungroupedStats = accumulator.getGroupStats(UNGROUPED_NAME);
accumulateGroupStatistics(data, date, ungroupedStats);
}
} }
/** /**
@ -856,6 +874,7 @@ import java.util.concurrent.atomic.AtomicInteger;
/** /**
* 从累加器生成最终统计结果 * 从累加器生成最终统计结果
* 修复遍历所有预定义的组确保"有成单但无进粉"的组也被统计
*/ */
private List<CustomerStatisticsData> generateStatisticsResults(String corpId,Date curDate,StatisticsAccumulator accumulator) { private List<CustomerStatisticsData> generateStatisticsResults(String corpId,Date curDate,StatisticsAccumulator accumulator) {
// 使用 Map 来存储每个指标对应的 CustomerStatisticsData // 使用 Map 来存储每个指标对应的 CustomerStatisticsData
@ -863,39 +882,42 @@ import java.util.concurrent.atomic.AtomicInteger;
Map<String, CustomerStatisticsData> indicatorMap = new LinkedHashMap<>(); Map<String, CustomerStatisticsData> indicatorMap = new LinkedHashMap<>();
//设置一个默认排序 //设置一个默认排序
int sortNo = 0; int sortNo = 0;
// 为每个组生成23个统计指标 // 为每个组生成统计指标 - 遍历所有预定义的组确保有成单但无进粉的组也被统计
for (Map.Entry<String, StatisticsAccumulator.GroupStatistics> entry : accumulator.getGroupStatsMap().entrySet()) { for (Map.Entry<String, String> groupEntry : GROUP_ATTR_MAP.entrySet()) {
String groupName = groupEntry.getKey();
String attr = groupEntry.getValue();
String groupName = entry.getKey(); // 获取或创建该组的统计器
StatisticsAccumulator.GroupStatistics stats = entry.getValue(); StatisticsAccumulator.GroupStatistics stats = accumulator.getGroupStats(groupName);
// 成单数需要从历史数据中获取成交日期 = date的数据
Long finishCount = customerExportDataMapper.selectByFinishDate(corpId, curDate, attr, finishFlag);
// 只有当有成单数或进粉数时才生成记录
if (finishCount > 0 || stats.getCustomerCount() > 0) {
// 21-23. 成本相关需要手工填写 // 21-23. 成本相关需要手工填写
setIndicatorValue(corpId,indicatorMap,curDate, "总成本(当日)", groupName, "需手工填写",(10*sortNo++)); setIndicatorValue(corpId,indicatorMap,curDate, "总成本(当日)", groupName, "需手工填写",(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "单条成本(当日)", groupName, "需手工填写",(10*sortNo++)); setIndicatorValue(corpId,indicatorMap,curDate, "单条成本(当日)", groupName, "需手工填写",(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "成单成本(当日)", groupName, "需手工填写",(10*sortNo++)); setIndicatorValue(corpId,indicatorMap,curDate, "成单成本(当日)", groupName, "需手工填写",(10*sortNo++));
// 1. 成单数 // 1. 成单数
//成单数 需要从历史的所有数据中获取 成交日期 = date的数据
Long finishCount = customerExportDataMapper.selectByFinishDate(corpId,curDate,GROUP_ATTR_MAP.get(groupName),finishFlag);
setIndicatorValue(corpId,indicatorMap,curDate, "成单数(当日)", groupName, String.valueOf(finishCount),(10*sortNo++)); setIndicatorValue(corpId,indicatorMap,curDate, "成单数(当日)", groupName, String.valueOf(finishCount),(10*sortNo++));
// 2. 进粉数 // 2. 进粉数
setIndicatorValue(corpId,indicatorMap,curDate, "进粉数(当日)", groupName, String.valueOf(stats.getCustomerCount()),(10*sortNo++)); setIndicatorValue(corpId,indicatorMap,curDate, "进粉数(当日)", groupName, String.valueOf(stats.getCustomerCount()),(10*sortNo++));
// 3. 转化率 = 成单数 / 进粉数使用finishCount而不是stats.getOrderCount() // 3. 转化率 = 成单数 / 进粉数
String conversionRate = calculateRate(finishCount.intValue(), stats.getCustomerCount()); String conversionRate = calculateRate(finishCount.intValue(), stats.getCustomerCount());
setIndicatorValue(corpId,indicatorMap,curDate, "转化率(当日)", groupName, conversionRate,(10*sortNo++)); setIndicatorValue(corpId,indicatorMap,curDate, "转化率(当日)", groupName, conversionRate,(10*sortNo++));
// 4. 及时单占比 = 及时单数 / 成单数当日 // 4. 及时单占比 = 及时单数 / 成单数当日
// 及时单数量需要从历史数据中获取根据成交日期和订单状态 Long timelyCount = customerExportDataMapper.selectTimelyOrderCount(corpId, curDate, attr, timelyFinishFlag);
Long timelyCount = customerExportDataMapper.selectTimelyOrderCount(corpId, curDate, GROUP_ATTR_MAP.get(groupName),timelyFinishFlag);
String timelyRate = calculateRate(timelyCount.intValue(), finishCount.intValue()); String timelyRate = calculateRate(timelyCount.intValue(), finishCount.intValue());
setIndicatorValue(corpId,indicatorMap,curDate, "及时单占比(当日)", groupName, timelyRate,(10*sortNo++)); setIndicatorValue(corpId,indicatorMap,curDate, "及时单占比(当日)", groupName, timelyRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "及时单数量(当日)", groupName, String.valueOf(timelyCount),(10*sortNo++),true); setIndicatorValue(corpId,indicatorMap,curDate, "及时单数量(当日)", groupName, String.valueOf(timelyCount),(10*sortNo++),true);
// 5. 非及时单占比 = 非及时单数 / 成单数当日 // 5. 非及时单占比 = 非及时单数 / 成单数当日
// 非及时单数量需要从历史数据中获取根据成交日期和订单状态 Long nonTimelyCount = customerExportDataMapper.selectNonTimelyOrderCount(corpId, curDate, attr, noTimelyfinishFlag);
Long nonTimelyCount = customerExportDataMapper.selectNonTimelyOrderCount(corpId, curDate, GROUP_ATTR_MAP.get(groupName),noTimelyfinishFlag);
String nonTimelyRate = calculateRate(nonTimelyCount.intValue(), finishCount.intValue()); String nonTimelyRate = calculateRate(nonTimelyCount.intValue(), finishCount.intValue());
setIndicatorValue(corpId,indicatorMap,curDate, "非及时单占比(当日)", groupName, nonTimelyRate,(10*sortNo++)); setIndicatorValue(corpId,indicatorMap,curDate, "非及时单占比(当日)", groupName, nonTimelyRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "非及时单数量(当日)", groupName, String.valueOf(nonTimelyCount),(10*sortNo++),true); setIndicatorValue(corpId,indicatorMap,curDate, "非及时单数量(当日)", groupName, String.valueOf(nonTimelyCount),(10*sortNo++),true);
@ -983,7 +1005,107 @@ import java.util.concurrent.atomic.AtomicInteger;
String studentDailyOrderRate = calculateRate(stats.getStudentDailyOrderCount(), stats.getStudentDailyCount()); String studentDailyOrderRate = calculateRate(stats.getStudentDailyOrderCount(), stats.getStudentDailyCount());
setIndicatorValue(corpId,indicatorMap,curDate, "学生出单率(当日)", groupName, studentDailyOrderRate,(10*sortNo++)); setIndicatorValue(corpId,indicatorMap,curDate, "学生出单率(当日)", groupName, studentDailyOrderRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "学生即时单数量(当日)", groupName, String.valueOf(stats.getStudentDailyOrderCount()),(10*sortNo++),true); setIndicatorValue(corpId,indicatorMap,curDate, "学生即时单数量(当日)", groupName, String.valueOf(stats.getStudentDailyOrderCount()),(10*sortNo++),true);
}
}
// 处理"未分组"数据
StatisticsAccumulator.GroupStatistics ungroupedStats = accumulator.getGroupStats(UNGROUPED_NAME);
Long ungroupedFinishCount = customerExportDataMapper.selectUngroupedFinishCount(corpId, curDate, finishFlag);
if (ungroupedFinishCount > 0 || ungroupedStats.getCustomerCount() > 0) {
// 21-23. 成本相关需要手工填写
setIndicatorValue(corpId,indicatorMap,curDate, "总成本(当日)", UNGROUPED_NAME, "需手工填写",(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "单条成本(当日)", UNGROUPED_NAME, "需手工填写",(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "成单成本(当日)", UNGROUPED_NAME, "需手工填写",(10*sortNo++));
// 1. 成单数
setIndicatorValue(corpId,indicatorMap,curDate, "成单数(当日)", UNGROUPED_NAME, String.valueOf(ungroupedFinishCount),(10*sortNo++));
// 2. 进粉数
setIndicatorValue(corpId,indicatorMap,curDate, "进粉数(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getCustomerCount()),(10*sortNo++));
// 3. 转化率
String conversionRate = calculateRate(ungroupedFinishCount.intValue(), ungroupedStats.getCustomerCount());
setIndicatorValue(corpId,indicatorMap,curDate, "转化率(当日)", UNGROUPED_NAME, conversionRate,(10*sortNo++));
// 4. 及时单占比
Long ungroupedTimelyCount = customerExportDataMapper.selectUngroupedTimelyOrderCount(corpId, curDate, timelyFinishFlag);
String timelyRate = calculateRate(ungroupedTimelyCount.intValue(), ungroupedFinishCount.intValue());
setIndicatorValue(corpId,indicatorMap,curDate, "及时单占比(当日)", UNGROUPED_NAME, timelyRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "及时单数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedTimelyCount),(10*sortNo++),true);
// 5. 非及时单占比
Long ungroupedNonTimelyCount = customerExportDataMapper.selectUngroupedNonTimelyOrderCount(corpId, curDate, noTimelyfinishFlag);
String nonTimelyRate = calculateRate(ungroupedNonTimelyCount.intValue(), ungroupedFinishCount.intValue());
setIndicatorValue(corpId,indicatorMap,curDate, "非及时单占比(当日)", UNGROUPED_NAME, nonTimelyRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "非及时单数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedNonTimelyCount),(10*sortNo++),true);
// 6-22 其他指标未分组记录的属性统计
setIndicatorValue(corpId,indicatorMap,curDate, "客户属性数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getTotalCustomerAttr()),(10*sortNo++));
String parentRate = calculateRate(ungroupedStats.getParentCount(), ungroupedStats.getTotalCustomerAttr());
setIndicatorValue(corpId,indicatorMap,curDate, "家长占比(当日)", UNGROUPED_NAME, parentRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "家长数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getParentCount()),(10*sortNo++),true);
String studentRate = calculateRate(ungroupedStats.getStudentCount(), ungroupedStats.getTotalCustomerAttr());
setIndicatorValue(corpId,indicatorMap,curDate, "学生占比(当日)", UNGROUPED_NAME, studentRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "学生数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getStudentCount()),(10*sortNo++),true);
String teacherRate = calculateRate(ungroupedStats.getTeacherCount(), ungroupedStats.getTotalCustomerAttr());
setIndicatorValue(corpId,indicatorMap,curDate, "老师占比(当日)", UNGROUPED_NAME, teacherRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "老师数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getTeacherCount()),(10*sortNo++),true);
String unknownRate = calculateRate(ungroupedStats.getUnknownAttrCount(), ungroupedStats.getTotalCustomerAttr());
setIndicatorValue(corpId,indicatorMap,curDate, "未知占比(当日)", UNGROUPED_NAME, unknownRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "未知数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getUnknownAttrCount()),(10*sortNo++),true);
setIndicatorValue(corpId,indicatorMap,curDate, "意向度数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getTotalIntention()),(10*sortNo++));
String activeQuoteRate = calculateRate(ungroupedStats.getActiveQuoteCount(), ungroupedStats.getTotalIntention());
setIndicatorValue(corpId,indicatorMap,curDate, "主动报价占比(当日)", UNGROUPED_NAME, activeQuoteRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "主动报价数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getActiveQuoteCount()),(10*sortNo++),true);
String passiveQuoteRate = calculateRate(ungroupedStats.getPassiveQuoteCount(), ungroupedStats.getTotalIntention());
setIndicatorValue(corpId,indicatorMap,curDate, "被动报价占比(当日)", UNGROUPED_NAME, passiveQuoteRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "被动报价数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getPassiveQuoteCount()),(10*sortNo++),true);
String noQuoteRate = calculateRate(ungroupedStats.getNoQuoteCount(), ungroupedStats.getTotalIntention());
setIndicatorValue(corpId,indicatorMap,curDate, "未开口报价占比(当日)", UNGROUPED_NAME, noQuoteRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "未开口报价数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getNoQuoteCount()),(10*sortNo++),true);
String deletedQuoteRate = calculateRate(ungroupedStats.getDeletedQuoteCount(), ungroupedStats.getTotalIntention());
setIndicatorValue(corpId,indicatorMap,curDate, "已删除报价占比(当日)", UNGROUPED_NAME, deletedQuoteRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "已删除数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getDeletedQuoteCount()),(10*sortNo++),true);
setIndicatorValue(corpId,indicatorMap,curDate, "年级数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getTotalGrade()),(10*sortNo++));
String primaryRate = calculateRate(ungroupedStats.getPrimaryCount(), ungroupedStats.getTotalGrade());
setIndicatorValue(corpId,indicatorMap,curDate, "小学占比(当日)", UNGROUPED_NAME, primaryRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "小学数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getPrimaryCount()),(10*sortNo++),true);
String middleRate = calculateRate(ungroupedStats.getMiddleCount(), ungroupedStats.getTotalGrade());
setIndicatorValue(corpId,indicatorMap,curDate, "初中占比(当日)", UNGROUPED_NAME, middleRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "初中数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getMiddleCount()),(10*sortNo++),true);
String highRate = calculateRate(ungroupedStats.getHighCount(), ungroupedStats.getTotalGrade());
setIndicatorValue(corpId,indicatorMap,curDate, "高中占比(当日)", UNGROUPED_NAME, highRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "高中数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getHighCount()),(10*sortNo++),true);
String parentOrderRate = calculateRate(ungroupedStats.getParentOrderCount(), ungroupedStats.getParentCount());
setIndicatorValue(corpId,indicatorMap,curDate, "家长出单占比(当日)", UNGROUPED_NAME, parentOrderRate,(10*sortNo++),true);
setIndicatorValue(corpId,indicatorMap,curDate, "家长出单数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getParentOrderCount()),(10*sortNo++),true);
String studentOrderRate = calculateRate(ungroupedStats.getStudentOrderCount(), ungroupedStats.getStudentCount());
setIndicatorValue(corpId,indicatorMap,curDate, "学生出单占比(当日)", UNGROUPED_NAME, studentOrderRate,(10*sortNo++),true);
setIndicatorValue(corpId,indicatorMap,curDate, "学生出单数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getStudentOrderCount()),(10*sortNo++),true);
String parentDailyOrderRate = calculateRate(ungroupedStats.getParentDailyOrderCount(), ungroupedStats.getParentDailyCount());
setIndicatorValue(corpId,indicatorMap,curDate, "家长出单率(当日)", UNGROUPED_NAME, parentDailyOrderRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "家长即时单数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getParentDailyOrderCount()),(10*sortNo++),true);
String studentDailyOrderRate = calculateRate(ungroupedStats.getStudentDailyOrderCount(), ungroupedStats.getStudentDailyCount());
setIndicatorValue(corpId,indicatorMap,curDate, "学生出单率(当日)", UNGROUPED_NAME, studentDailyOrderRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "学生即时单数量(当日)", UNGROUPED_NAME, String.valueOf(ungroupedStats.getStudentDailyOrderCount()),(10*sortNo++),true);
} }
// Map 转换为 List 返回 // Map 转换为 List 返回
@ -1097,10 +1219,12 @@ import java.util.concurrent.atomic.AtomicInteger;
/** /**
* 处理单条数据记录累加到部门统计中 * 处理单条数据记录累加到部门统计中
* 修复添加对tag_group7成单状态的验证
*/ */
private void processDepartmentRecord(CustomerExportData data, Date targetDate, private void processDepartmentRecord(CustomerExportData data, Date targetDate,
DepartmentStatisticsAccumulator.DepartmentStats stats) { DepartmentStatisticsAccumulator.DepartmentStats stats) {
if(matchesQValue(data,targetDate)) { // 成单统计需要同时满足成交日期匹配 AND 成单状态匹配
if(matchesQValue(data,targetDate) && isOrderCompleted(data)) {
stats.setTotalOrderCount(stats.getTotalOrderCount() + 1); stats.setTotalOrderCount(stats.getTotalOrderCount() + 1);
// 及时单和非及时单统计 // 及时单和非及时单统计

View File

@ -45,6 +45,8 @@ public class HandleAllDataV2 {
private List<String> finishFlag = Arrays.asList("已成交及时单9元+", "已成交非及时单9元+"); private List<String> finishFlag = Arrays.asList("已成交及时单9元+", "已成交非及时单9元+");
private List<String> timelyFinishFlag = Arrays.asList("已成交及时单9元+"); private List<String> timelyFinishFlag = Arrays.asList("已成交及时单9元+");
private List<String> noTimelyfinishFlag = Arrays.asList("已成交非及时单9元+"); private List<String> noTimelyfinishFlag = Arrays.asList("已成交非及时单9元+");
private static final String UNGROUPED_NAME = "未分组";
/** /**
* 组名到字段名的映射使用括号内的名称 * 组名到字段名的映射使用括号内的名称
*/ */
@ -201,6 +203,8 @@ public class HandleAllDataV2 {
* 处理单条数据记录累加到组级和标签级统计 * 处理单条数据记录累加到组级和标签级统计
*/ */
private void processDataRecordV2(CustomerExportData data, Date date, GroupTagAccumulator accumulator) { private void processDataRecordV2(CustomerExportData data, Date date, GroupTagAccumulator accumulator) {
boolean hasGroup = false;
// 遍历所有组 // 遍历所有组
for (Map.Entry<String, String> entry : GROUP_FIELD_MAP.entrySet()) { for (Map.Entry<String, String> entry : GROUP_FIELD_MAP.entrySet()) {
String groupName = entry.getKey(); String groupName = entry.getKey();
@ -214,6 +218,8 @@ public class HandleAllDataV2 {
continue; continue;
} }
hasGroup = true;
// 获取该组的统计器 // 获取该组的统计器
GroupStatistics groupStats = accumulator.getGroupStats(groupName); GroupStatistics groupStats = accumulator.getGroupStats(groupName);
@ -231,6 +237,12 @@ public class HandleAllDataV2 {
accumulateGroupStatistics(data, date, tagStats); accumulateGroupStatistics(data, date, tagStats);
} }
} }
// 如果不属于任何组统计到"未分组"
if (!hasGroup) {
GroupStatistics ungroupedStats = accumulator.getGroupStats(UNGROUPED_NAME);
accumulateGroupStatistics(data, date, ungroupedStats);
}
} }
/** /**
@ -256,11 +268,9 @@ public class HandleAllDataV2 {
stats.setOrderCount(stats.getOrderCount() + 1); stats.setOrderCount(stats.getOrderCount() + 1);
String orderStatus = data.getTagGroup7(); String orderStatus = data.getTagGroup7();
if (orderStatus != null) { if (orderStatus != null) {
String[] split = orderStatus.split(","); if (orderStatus.equals("已成交及时单9元+")) {
String statusInfo = split[split.length - 1];
if (statusInfo.contains("已成交及时单9元+")) {
stats.setTimelyOrderCount(stats.getTimelyOrderCount() + 1); stats.setTimelyOrderCount(stats.getTimelyOrderCount() + 1);
} else if (statusInfo.contains("已成交非及时单9元+")) { } else if (orderStatus.equals("已成交非及时单9元+")) {
stats.setNonTimelyOrderCount(stats.getNonTimelyOrderCount() + 1); stats.setNonTimelyOrderCount(stats.getNonTimelyOrderCount() + 1);
} }
} }
@ -342,46 +352,79 @@ public class HandleAllDataV2 {
/** /**
* 从累加器生成最终统计结果V2 * 从累加器生成最终统计结果V2
* 修复遍历所有预定义的组确保"有成单但无进粉"的组也被统计
*/ */
private List<CustomerStatisticsDataV2> generateStatisticsResultsV2( private List<CustomerStatisticsDataV2> generateStatisticsResultsV2(
String corpId, Date date, GroupTagAccumulator accumulator) { String corpId, Date date, GroupTagAccumulator accumulator) {
List<CustomerStatisticsDataV2> result = new ArrayList<>(); List<CustomerStatisticsDataV2> result = new ArrayList<>();
int sortNo = 0; int sortNo = 0;
long tempId = 1; // 临时ID生成器 long tempId = 1;
// 1. 生成组级数据 // 1. 生成组级数据 - 遍历所有预定义的组确保有成单但无进粉的组也被统计
Map<String, Long> groupIdMap = new HashMap<>(); Map<String, Long> groupIdMap = new HashMap<>();
for (Map.Entry<String, GroupStatistics> entry : accumulator.getGroupStatsMap().entrySet()) { for (Map.Entry<String, String> groupEntry : GROUP_FIELD_MAP.entrySet()) {
String groupName = entry.getKey(); String groupName = groupEntry.getKey();
GroupStatistics stats = entry.getValue(); String attr = GROUP_ATTR_MAP.get(groupName);
// 获取或创建该组的统计器
GroupStatistics stats = accumulator.getGroupStats(groupName);
// 使用SQL查询获取成单数与V1保持一致 // 使用SQL查询获取成单数与V1保持一致
Long finishCount = customerExportDataMapper.selectByFinishDate( Long finishCount = customerExportDataMapper.selectByFinishDate(
corpId, date, GROUP_ATTR_MAP.get(groupName),finishFlag); corpId, date, attr, finishFlag);
stats.setOrderCount(finishCount.intValue()); stats.setOrderCount(finishCount.intValue());
// 使用SQL查询获取及时单数量根据成交日期和订单状态 // 使用SQL查询获取及时单数量根据成交日期和订单状态
Long timelyCount = customerExportDataMapper.selectTimelyOrderCount( Long timelyCount = customerExportDataMapper.selectTimelyOrderCount(
corpId, date, GROUP_ATTR_MAP.get(groupName),timelyFinishFlag); corpId, date, attr, timelyFinishFlag);
stats.setTimelyOrderCount(timelyCount.intValue()); stats.setTimelyOrderCount(timelyCount.intValue());
// 使用SQL查询获取非及时单数量根据成交日期和订单状态 // 使用SQL查询获取非及时单数量根据成交日期和订单状态
Long nonTimelyCount = customerExportDataMapper.selectNonTimelyOrderCount( Long nonTimelyCount = customerExportDataMapper.selectNonTimelyOrderCount(
corpId, date, GROUP_ATTR_MAP.get(groupName),noTimelyfinishFlag); corpId, date, attr, noTimelyfinishFlag);
stats.setNonTimelyOrderCount(nonTimelyCount.intValue()); stats.setNonTimelyOrderCount(nonTimelyCount.intValue());
// 只有当有成单数或进粉数时才生成记录
if (stats.getOrderCount() > 0 || stats.getCustomerCount() > 0) {
CustomerStatisticsDataV2 groupData = createStatisticsDataV2( CustomerStatisticsDataV2 groupData = createStatisticsDataV2(
corpId, date, groupName, null, stats, sortNo++); corpId, date, groupName, null, stats, sortNo++);
groupData.setDataLevel(1); groupData.setDataLevel(1);
groupData.setId(tempId); // 设置临时ID groupData.setId(tempId);
result.add(groupData); result.add(groupData);
// 临时存储组ID用于标签级数据的parentId
groupIdMap.put(groupName, tempId); groupIdMap.put(groupName, tempId);
tempId++; tempId++;
} }
}
// 2. 生成标签级数据 // 2. 处理"未分组"数据
GroupStatistics ungroupedStats = accumulator.getGroupStats(UNGROUPED_NAME);
// 查询未分组记录的成单数
Long ungroupedFinishCount = customerExportDataMapper.selectUngroupedFinishCount(
corpId, date, finishFlag);
ungroupedStats.setOrderCount(ungroupedFinishCount.intValue());
// 查询未分组记录的及时单数量
Long ungroupedTimelyCount = customerExportDataMapper.selectUngroupedTimelyOrderCount(
corpId, date, timelyFinishFlag);
ungroupedStats.setTimelyOrderCount(ungroupedTimelyCount.intValue());
// 查询未分组记录的非及时单数量
Long ungroupedNonTimelyCount = customerExportDataMapper.selectUngroupedNonTimelyOrderCount(
corpId, date, noTimelyfinishFlag);
ungroupedStats.setNonTimelyOrderCount(ungroupedNonTimelyCount.intValue());
// 只有当有成单数或进粉数时才生成记录
if (ungroupedStats.getOrderCount() > 0 || ungroupedStats.getCustomerCount() > 0) {
CustomerStatisticsDataV2 ungroupedData = createStatisticsDataV2(
corpId, date, UNGROUPED_NAME, null, ungroupedStats, sortNo++);
ungroupedData.setDataLevel(1);
ungroupedData.setId(tempId);
result.add(ungroupedData);
tempId++;
}
// 3. 生成标签级数据
for (Map.Entry<String, Map<String, TagStatistics>> groupEntry : for (Map.Entry<String, Map<String, TagStatistics>> groupEntry :
accumulator.getTagStatsMap().entrySet()) { accumulator.getTagStatsMap().entrySet()) {
String groupName = groupEntry.getKey(); String groupName = groupEntry.getKey();
@ -393,23 +436,23 @@ public class HandleAllDataV2 {
// 使用SQL查询获取该标签的成单数根据标签值筛选 // 使用SQL查询获取该标签的成单数根据标签值筛选
Long finishCount = customerExportDataMapper.selectByFinishDateAndTag( Long finishCount = customerExportDataMapper.selectByFinishDateAndTag(
corpId, date, GROUP_ATTR_MAP.get(groupName), tagName,finishFlag); corpId, date, GROUP_ATTR_MAP.get(groupName), tagName, finishFlag);
stats.setOrderCount(finishCount.intValue()); stats.setOrderCount(finishCount.intValue());
// 使用SQL查询获取该标签的及时单数量 // 使用SQL查询获取该标签的及时单数量
Long timelyCount = customerExportDataMapper.selectTimelyOrderCountByTag( Long timelyCount = customerExportDataMapper.selectTimelyOrderCountByTag(
corpId, date, GROUP_ATTR_MAP.get(groupName), tagName,timelyFinishFlag); corpId, date, GROUP_ATTR_MAP.get(groupName), tagName, timelyFinishFlag);
stats.setTimelyOrderCount(timelyCount.intValue()); stats.setTimelyOrderCount(timelyCount.intValue());
// 使用SQL查询获取该标签的非及时单数量 // 使用SQL查询获取该标签的非及时单数量
Long nonTimelyCount = customerExportDataMapper.selectNonTimelyOrderCountByTag( Long nonTimelyCount = customerExportDataMapper.selectNonTimelyOrderCountByTag(
corpId, date, GROUP_ATTR_MAP.get(groupName), tagName,noTimelyfinishFlag); corpId, date, GROUP_ATTR_MAP.get(groupName), tagName, noTimelyfinishFlag);
stats.setNonTimelyOrderCount(nonTimelyCount.intValue()); stats.setNonTimelyOrderCount(nonTimelyCount.intValue());
CustomerStatisticsDataV2 tagData = createStatisticsDataV2( CustomerStatisticsDataV2 tagData = createStatisticsDataV2(
corpId, date, groupName, tagName, stats, sortNo++); corpId, date, groupName, tagName, stats, sortNo++);
tagData.setDataLevel(2); tagData.setDataLevel(2);
tagData.setId(tempId); // 设置临时ID tagData.setId(tempId);
tagData.setParentId(parentId); tagData.setParentId(parentId);
result.add(tagData); result.add(tagData);
tempId++; tempId++;
@ -523,10 +566,13 @@ public class HandleAllDataV2 {
/** /**
* 检查数据来源是否匹配 * 检查数据来源是否匹配
* 排除"由管理员XXX分配"的记录
*/ */
private boolean matchesSource(CustomerExportData data) { private boolean matchesSource(CustomerExportData data) {
if (data.getSource() != null && if(data == null || data.getSource() == null) {
data.getSource().contains("管理员") && return true;
}
if (data.getSource().contains("管理员") &&
data.getSource().contains("分配")) { data.getSource().contains("分配")) {
return false; return false;
} }

View File

@ -240,5 +240,41 @@ public interface CustomerExportDataMapper extends BaseMapper<CustomerExportData>
@Param("corpId") String corpId, @Param("corpId") String corpId,
@Param("startDate") Date startDate, @Param("startDate") Date startDate,
@Param("endDate") Date endDate,@Param("successFlags") List<String> successFlags); @Param("endDate") Date endDate,@Param("successFlags") List<String> successFlags);
/**
* 查询未分组记录的成单数所有组字段都为空
* @param corpId 企业ID
* @param date 成交日期
* @param successFlags 成单状态标志
* @return 成单数
*/
Long selectUngroupedFinishCount(
@Param("corpId") String corpId,
@Param("date") Date date,
@Param("successFlags") List<String> successFlags);
/**
* 查询未分组记录的及时单数量
* @param corpId 企业ID
* @param date 成交日期
* @param successFlags 及时单状态标志
* @return 及时单数量
*/
Long selectUngroupedTimelyOrderCount(
@Param("corpId") String corpId,
@Param("date") Date date,
@Param("successFlags") List<String> successFlags);
/**
* 查询未分组记录的非及时单数量
* @param corpId 企业ID
* @param date 成交日期
* @param successFlags 非及时单状态标志
* @return 非及时单数量
*/
Long selectUngroupedNonTimelyOrderCount(
@Param("corpId") String corpId,
@Param("date") Date date,
@Param("successFlags") List<String> successFlags);
} }

View File

@ -702,4 +702,52 @@
</if> </if>
</select> </select>
<!-- 查询未分组记录的成单数(所有组字段都为空) -->
<select id="selectUngroupedFinishCount" resultType="java.lang.Long">
SELECT COUNT(*)
FROM customer_export_data
WHERE corp_id = #{corpId}
AND finish_date = #{date}
AND tag_group7 IN
<foreach collection="successFlags" item="successFlag" open="(" separator="," close=")">
#{successFlag}
</foreach>
AND tag_group1 IS NULL AND tag_group2 IS NULL AND tag_group3 IS NULL
AND tag_group10 IS NULL AND tag_group11 IS NULL AND tag_group12 IS NULL
AND tag_group13 IS NULL AND tag_group14 IS NULL AND tag_group16 IS NULL
AND tag_group17 IS NULL AND tag_group18 IS NULL
</select>
<!-- 查询未分组记录的及时单数量 -->
<select id="selectUngroupedTimelyOrderCount" resultType="java.lang.Long">
SELECT COUNT(*)
FROM customer_export_data
WHERE corp_id = #{corpId}
AND finish_date = #{date}
AND tag_group7 IN
<foreach collection="successFlags" item="successFlag" open="(" separator="," close=")">
#{successFlag}
</foreach>
AND tag_group1 IS NULL AND tag_group2 IS NULL AND tag_group3 IS NULL
AND tag_group10 IS NULL AND tag_group11 IS NULL AND tag_group12 IS NULL
AND tag_group13 IS NULL AND tag_group14 IS NULL AND tag_group16 IS NULL
AND tag_group17 IS NULL AND tag_group18 IS NULL
</select>
<!-- 查询未分组记录的非及时单数量 -->
<select id="selectUngroupedNonTimelyOrderCount" resultType="java.lang.Long">
SELECT COUNT(*)
FROM customer_export_data
WHERE corp_id = #{corpId}
AND finish_date = #{date}
AND tag_group7 IN
<foreach collection="successFlags" item="successFlag" open="(" separator="," close=")">
#{successFlag}
</foreach>
AND tag_group1 IS NULL AND tag_group2 IS NULL AND tag_group3 IS NULL
AND tag_group10 IS NULL AND tag_group11 IS NULL AND tag_group12 IS NULL
AND tag_group13 IS NULL AND tag_group14 IS NULL AND tag_group16 IS NULL
AND tag_group17 IS NULL AND tag_group18 IS NULL
</select>
</mapper> </mapper>