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

@@ -0,0 +1,119 @@
<?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="com.viewsh.module.ops.dal.mysql.workorder.OpsOrderMapper">
<!-- 按日期分组统计工单创建数 -->
<select id="selectCreatedCountGroupByDate" resultType="com.viewsh.module.ops.controller.admin.workorder.vo.statistics.DateCountRespVO">
SELECT DATE(create_time) AS statDate, COUNT(*) AS cnt
FROM ops_order
WHERE order_type = #{orderType}
AND deleted = 0
AND create_time &gt;= #{startTime}
AND create_time &lt; #{endTime}
GROUP BY DATE(create_time)
ORDER BY statDate
</select>
<!-- 按日期分组统计工单完成数 -->
<select id="selectCompletedCountGroupByDate" resultType="com.viewsh.module.ops.controller.admin.workorder.vo.statistics.DateCountRespVO">
SELECT DATE(end_time) AS statDate, COUNT(*) AS cnt
FROM ops_order
WHERE order_type = #{orderType}
AND status = 'COMPLETED'
AND deleted = 0
AND end_time &gt;= #{startTime}
AND end_time &lt; #{endTime}
GROUP BY DATE(end_time)
ORDER BY statDate
</select>
<!-- 按日期分组统计平均响应时长和完成时长 -->
<select id="selectAvgTimeGroupByDate" resultType="com.viewsh.module.ops.controller.admin.workorder.vo.statistics.AvgTimeRespVO">
SELECT DATE(end_time) AS statDate,
AVG(CASE WHEN response_seconds > 0 THEN response_seconds ELSE NULL END) AS avgResponse,
AVG(CASE WHEN completion_seconds > 0 THEN completion_seconds ELSE NULL END) AS avgCompletion
FROM ops_order
WHERE order_type = #{orderType}
AND status = 'COMPLETED'
AND deleted = 0
AND end_time &gt;= #{startTime}
AND end_time &lt; #{endTime}
GROUP BY DATE(end_time)
ORDER BY statDate
</select>
<!-- 按区域分组统计工单数和完成数 -->
<select id="selectCountGroupByAreaId" resultType="com.viewsh.module.ops.controller.admin.workorder.vo.statistics.AreaCountRespVO">
SELECT area_id AS areaId,
COUNT(*) AS totalCount,
SUM(CASE WHEN status = 'COMPLETED' THEN 1 ELSE 0 END) AS completedCount
FROM ops_order
WHERE order_type = #{orderType}
AND status != 'CANCELLED'
AND deleted = 0
AND area_id IS NOT NULL
GROUP BY area_id
ORDER BY totalCount DESC
LIMIT 10
</select>
<!-- 按小时分组统计工单创建数 -->
<select id="selectCountGroupByHour" resultType="com.viewsh.module.ops.controller.admin.workorder.vo.statistics.HourCountRespVO">
SELECT HOUR(create_time) AS hourVal, COUNT(*) AS cnt
FROM ops_order
WHERE order_type = #{orderType}
AND deleted = 0
AND create_time &gt;= #{startTime}
AND create_time &lt; #{endTime}
GROUP BY HOUR(create_time)
ORDER BY hourVal
</select>
<!-- 按星期和小时分组统计(热力图) -->
<select id="selectCountGroupByDayOfWeekAndHour" resultType="com.viewsh.module.ops.controller.admin.workorder.vo.statistics.HeatmapRespVO">
SELECT DAYOFWEEK(create_time) AS dayOfWeek,
HOUR(create_time) AS hourVal,
COUNT(*) AS cnt
FROM ops_order
WHERE order_type = #{orderType}
AND deleted = 0
AND create_time &gt;= #{startTime}
AND create_time &lt; #{endTime}
GROUP BY DAYOFWEEK(create_time), HOUR(create_time)
ORDER BY dayOfWeek, hourVal
</select>
<!-- 按保洁类型分组统计平均作业时长JOIN clean_ext -->
<select id="selectAvgDurationGroupByCleaningType" resultType="com.viewsh.module.ops.controller.admin.workorder.vo.statistics.CleaningTypeAvgDurationRespVO">
SELECT ext.cleaning_type AS cleaningType,
ROUND(AVG(TIMESTAMPDIFF(MINUTE, ext.arrived_time, ext.completed_time))) AS avgDuration
FROM ops_order_clean_ext ext
INNER JOIN ops_order o ON ext.ops_order_id = o.id
WHERE o.status = 'COMPLETED'
AND o.order_type = #{orderType}
AND o.deleted = 0
AND ext.deleted = 0
AND ext.completed_time IS NOT NULL
AND ext.arrived_time IS NOT NULL
AND ext.cleaning_type IS NOT NULL
GROUP BY ext.cleaning_type
</select>
<!-- 按功能类型分组统计工单数和完成数 -->
<select id="selectCountGroupByFunctionType" resultType="com.viewsh.module.ops.controller.admin.workorder.vo.statistics.FunctionTypeCountRespVO">
SELECT a.function_type AS functionType,
COUNT(o.id) AS totalCount,
SUM(CASE WHEN o.status = 'COMPLETED' THEN 1 ELSE 0 END) AS completedCount
FROM ops_order o
INNER JOIN ops_bus_area a ON o.area_id = a.id
WHERE o.order_type = #{orderType}
AND o.status != 'CANCELLED'
AND o.deleted = 0
AND a.deleted = 0
AND a.function_type IS NOT NULL
GROUP BY a.function_type
ORDER BY totalCount DESC
LIMIT 10
</select>
</mapper>