feat(wms/material-coil): 优化钢卷囤积统计查询性能

1. 重构囤积统计方法:将原Java循环计算逻辑替换为单SQL聚合查询,通过JSON_EXTRACT解析二维码步骤创建时间,一次性计算平均囤积周期与成本
2. 移除原低效实现:删除getHoardingStatistics方法中的批量查询与循环解析代码,消除N+1性能问题
3. 新增Mapper方法与XML映射:添加selectHoardingStatistics接口及对应SQL,支持与分页查询相同的条件筛选

调整前,统计需先查询钢卷列表再批量获取二维码并循环解析,存在性能瓶颈;调整后,通过单SQL完成所有聚合计算,大幅提升查询效率,支持大规模数据统计。
This commit is contained in:
2026-06-04 17:06:08 +08:00
parent 29c21fd64f
commit 705d929d6e
3 changed files with 69 additions and 117 deletions

View File

@@ -984,6 +984,39 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
${ew.customSqlSegment}
</select>
<!-- 统计已发货钢卷的囤积周期和囤积成本在selectStatistics基础上JOIN二维码表解析steps[0].create_time -->
<select id="selectHoardingStatistics" resultType="java.util.Map">
SELECT
COUNT(*) AS total_count,
ROUND(AVG(hoarding_seconds / 86400), 2) AS avg_hoarding_days,
ROUND(AVG(hoarding_seconds / 86400 * net_weight), 2) AS avg_hoarding_cost
FROM (
SELECT
IFNULL(mc.net_weight, 0) AS net_weight,
TIMESTAMPDIFF(SECOND,
FROM_UNIXTIME(JSON_EXTRACT(wgr.content, '$.steps[0].create_time') / 1000),
COALESCE(mc.export_time, mc.update_time)
) AS hoarding_seconds
FROM wms_material_coil mc
INNER JOIN wms_generate_record wgr ON mc.qrcode_record_id = wgr.record_id
AND JSON_EXTRACT(wgr.content, '$.steps[0].create_time') IS NOT NULL
LEFT JOIN wms_warehouse w ON mc.warehouse_id = w.warehouse_id
LEFT JOIN wms_warehouse nw ON mc.next_warehouse_id = nw.warehouse_id
LEFT JOIN wms_actual_warehouse aw ON mc.actual_warehouse_id = aw.actual_warehouse_id
LEFT JOIN sys_user su ON mc.sale_id = su.user_id
LEFT JOIN wms_raw_material rm ON mc.item_type = 'raw_material' AND mc.item_id = rm.raw_material_id
LEFT JOIN wms_product p ON mc.item_type = 'product' AND mc.item_id = p.product_id
LEFT JOIN (
SELECT coil_id, COUNT(*) AS abnormal_count
FROM wms_coil_abnormal
WHERE del_flag = 0
GROUP BY coil_id
) ca ON mc.coil_id = ca.coil_id
${ew.customSqlSegment}
) t
WHERE t.hoarding_seconds > 0
</select>
<!-- 统计仓库使用次数按warehouse_id出现次数排序 -->
<select id="selectWarehouseIdCount" resultType="java.util.Map">
SELECT warehouse_id, COUNT(*) AS coil_count