feat(ops): 实现工单统计看板功能
Some checks failed
Java CI with Maven / build (11) (push) Has been cancelled
Java CI with Maven / build (17) (push) Has been cancelled
Java CI with Maven / build (8) (push) Has been cancelled

1. 修复 MyBatis 类型安全问题
   - 创建 9 个 DTO 类替换 List<Map<String, Object>>
   - 修复 @MapKey 错误,使用强类型返回值

2. 实现工单统计看板 5 大功能
   - 漏斗统计:支持时间范围过滤
   - 时段热力图:改为近 7 天,Y 轴显示日期(MM-dd)
   - 功能类型排行:替换区域排行,JOIN ops_bus_area 表
   - 今日工单时段分布:X 轴优化为每 2 小时展示
   - 近七天客流统计:独立接口,支持工作台实时趋势

3. 字典转换实现
   - 新增 DictTypeConstants.OPS_AREA_FUNCTION_TYPE(保留供未来扩展)
   - 使用硬编码 Map 实现功能类型中文转换(性能最优)
   - 添加 TODO 说明未来可切换 DictFrameworkUtils

4. SQL 优化
   - 功能类型统计:INNER JOIN ops_bus_area 表
   - 热力图查询:按日期和小时分组统计
   - 时段分布:仅统计当天数据

5. 缓存策略
   - 看板统计:5 分钟缓存(@Cacheable)
   - 客流监测:5 分钟缓存
   - 防止高并发查询压力

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
lzh
2026-02-10 23:28:02 +08:00
parent 113e90c726
commit 16441e7c25
19 changed files with 1630 additions and 2 deletions

View File

@@ -55,6 +55,11 @@ public class CleanWorkOrderServiceImpl implements CleanWorkOrderService {
EVENT_TYPE_NAMES.put("COMPLETE", "工单完成");
EVENT_TYPE_NAMES.put("CANCEL", "工单取消");
EVENT_TYPE_NAMES.put("UPGRADE_PRIORITY", "优先级升级");
EVENT_TYPE_NAMES.put("ENQUEUE", "任务入队");
EVENT_TYPE_NAMES.put("QUEUED", "排队中");
EVENT_TYPE_NAMES.put("DISPATCH", "任务派发");
EVENT_TYPE_NAMES.put("DISPATCHED", "已派发");
EVENT_TYPE_NAMES.put("CONFIRMED", "已确认");
}
@Override
@@ -75,9 +80,29 @@ public class CleanWorkOrderServiceImpl implements CleanWorkOrderService {
);
// 3. 转换为时间轴节点
List<OrderTimelineRespDTO.TimelineItemDTO> timeline = events.stream()
List<OrderTimelineRespDTO.TimelineItemDTO> timeline = new java.util.ArrayList<>();
// 3.1 补充工单创建节点PENDING
boolean hasPendingNode = events.stream()
.anyMatch(e -> "PENDING".equals(e.getToStatus()) || "CREATE".equals(e.getEventType()));
if (!hasPendingNode) {
OrderTimelineRespDTO.TimelineItemDTO pendingNode = OrderTimelineRespDTO.TimelineItemDTO.builder()
.status("PENDING")
.statusName("待分配")
.time(formatDateTime(order.getCreateTime()))
.operator("系统")
.description("工单已创建")
.extra(buildPendingExtraInfo(order))
.build();
timeline.add(pendingNode);
}
// 3.2 添加事件节点
List<OrderTimelineRespDTO.TimelineItemDTO> eventNodes = events.stream()
.map(this::convertToTimelineItem)
.toList();
timeline.addAll(eventNodes);
// 4. 构建响应
return OrderTimelineRespDTO.builder()
@@ -195,8 +220,14 @@ public class CleanWorkOrderServiceImpl implements CleanWorkOrderService {
}
}
// 优先使用 toStatus如果为空则使用 eventType
String status = event.getToStatus();
if (status == null || status.isEmpty()) {
status = event.getEventType();
}
return OrderTimelineRespDTO.TimelineItemDTO.builder()
.status(event.getToStatus())
.status(status)
.statusName(statusName)
.time(formatDateTime(event.getEventTime()))
.operator(operator)
@@ -227,4 +258,20 @@ public class CleanWorkOrderServiceImpl implements CleanWorkOrderService {
}
return extra;
}
/**
* 构建 PENDING 节点的额外信息
*/
private Map<String, Object> buildPendingExtraInfo(OpsOrderDO order) {
Map<String, Object> extra = new HashMap<>();
extra.put("event_type", "CREATE");
extra.put("operator_type", "SYSTEM");
extra.put("order_code", order.getOrderCode());
extra.put("priority", order.getPriority());
extra.put("source_type", order.getSourceType());
if (order.getTriggerSource() != null) {
extra.put("trigger_source", order.getTriggerSource());
}
return extra;
}
}