feat(stock): 优化实际库区查询速率使用CTE递归查询

- 修改 WmsStockMapper 接口,增加 rootWarehouseId 参数用于限定查询范围
- 优化 WmsStockMapper.xml 中的 SQL 查询逻辑,引入 CTE 递归查询子仓库数据
- 调整查询语句结构,将分组统计与关联查询分离以提升性能
- 移除 Java 层递归获取子仓库 ID 的逻辑,改为数据库端处理
- 强制使用指定索引 idx_mc_fixed_group 提高查询效率
- 更新服务实现类传参逻辑,传递实际仓库 ID 用于构建查询条件
This commit is contained in:
2025-12-18 09:41:22 +08:00
parent 547a55b1b5
commit 51506bbb66
3 changed files with 64 additions and 74 deletions

View File

@@ -91,40 +91,64 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
ORDER BY totalQuantity DESC
</select>
<select id="selectVoPagePlusActual" resultType="com.klp.domain.vo.WmsStockVo">
<if test="rootWarehouseId != null">
WITH RECURSIVE aw_tree AS (
SELECT aw.actual_warehouse_id
FROM wms_actual_warehouse aw
WHERE aw.actual_warehouse_id = #{rootWarehouseId} AND aw.del_flag = 0
UNION ALL
SELECT c.actual_warehouse_id
FROM wms_actual_warehouse c
INNER JOIN aw_tree p ON c.parent_id = p.actual_warehouse_id
WHERE c.del_flag = 0
)
</if>
SELECT
mc.actual_warehouse_id AS actualWarehouseId,
mc.item_type AS itemType,
mc.item_id AS itemId,
MIN(w.actual_warehouse_name) AS actualWarehouseName,
MIN(CASE WHEN mc.item_type = 'product' THEN p.product_name
WHEN mc.item_type = 'raw_material' THEN r.raw_material_name
ELSE NULL END) AS itemName,
MIN(CASE WHEN mc.item_type = 'product' THEN p.product_code
WHEN mc.item_type = 'raw_material' THEN r.raw_material_code
ELSE NULL END) AS itemCode,
MIN(CASE WHEN mc.item_type = 'product' THEN p.specification
WHEN mc.item_type = 'raw_material' THEN r.specification
ELSE NULL END) AS specification,
MIN(CASE WHEN mc.item_type = 'product' THEN p.material
WHEN mc.item_type = 'raw_material' THEN r.material
ELSE NULL END) AS material,
MIN(CASE WHEN mc.item_type = 'product' THEN p.surface_treatment_desc
WHEN mc.item_type = 'raw_material' THEN r.surface_treatment_desc
ELSE NULL END) AS surfaceTreatmentDesc,
MIN(CASE WHEN mc.item_type = 'product' THEN p.zinc_layer
WHEN mc.item_type = 'raw_material' THEN r.zinc_layer
ELSE NULL END) AS zincLayer,
MIN(CASE WHEN mc.item_type = 'product' THEN p.manufacturer
WHEN mc.item_type = 'raw_material' THEN r.manufacturer
ELSE NULL END) AS manufacturer,
COUNT(*) AS totalQuantity,
SUM(CASE WHEN mc.status = 1 THEN 1 ELSE 0 END) AS onTheWay
FROM wms_material_coil mc
LEFT JOIN wms_actual_warehouse w ON mc.actual_warehouse_id = w.actual_warehouse_id AND w.del_flag = 0
LEFT JOIN wms_product p ON mc.item_type = 'product' AND mc.item_id = p.product_id AND p.del_flag = 0
LEFT JOIN wms_raw_material r ON mc.item_type = 'raw_material' AND mc.item_id = r.raw_material_id AND r.del_flag = 0
${ew.customSqlSegment}
GROUP BY mc.actual_warehouse_id, mc.item_type, mc.item_id
g.actual_warehouse_id AS actualWarehouseId,
g.item_type AS itemType,
g.item_id AS itemId,
w.actual_warehouse_name AS actualWarehouseName,
CASE WHEN g.item_type = 'product' THEN p.product_name
WHEN g.item_type = 'raw_material' THEN r.raw_material_name
ELSE NULL END AS itemName,
CASE WHEN g.item_type = 'product' THEN p.product_code
WHEN g.item_type = 'raw_material' THEN r.raw_material_code
ELSE NULL END AS itemCode,
CASE WHEN g.item_type = 'product' THEN p.specification
WHEN g.item_type = 'raw_material' THEN r.specification
ELSE NULL END AS specification,
CASE WHEN g.item_type = 'product' THEN p.material
WHEN g.item_type = 'raw_material' THEN r.material
ELSE NULL END AS material,
CASE WHEN g.item_type = 'product' THEN p.surface_treatment_desc
WHEN g.item_type = 'raw_material' THEN r.surface_treatment_desc
ELSE NULL END AS surfaceTreatmentDesc,
CASE WHEN g.item_type = 'product' THEN p.zinc_layer
WHEN g.item_type = 'raw_material' THEN r.zinc_layer
ELSE NULL END AS zincLayer,
CASE WHEN g.item_type = 'product' THEN p.manufacturer
WHEN g.item_type = 'raw_material' THEN r.manufacturer
ELSE NULL END AS manufacturer,
g.totalQuantity,
g.onTheWay
FROM (
SELECT mc.actual_warehouse_id,
mc.item_type,
mc.item_id,
COUNT(*) AS totalQuantity,
SUM(CASE WHEN mc.status = 1 THEN 1 ELSE 0 END) AS onTheWay
FROM wms_material_coil mc FORCE INDEX (idx_mc_fixed_group)
${ew.customSqlSegment}
<if test="rootWarehouseId != null">
-- 过滤仓库ID仅包含CTE查询出的根/子仓库
AND mc.actual_warehouse_id IN (SELECT actual_warehouse_id FROM aw_tree)
</if>
GROUP BY mc.actual_warehouse_id, mc.item_type, mc.item_id
) g
LEFT JOIN wms_actual_warehouse w ON g.actual_warehouse_id = w.actual_warehouse_id AND w.del_flag = 0
LEFT JOIN wms_product p ON g.item_type = 'product' AND g.item_id = p.product_id AND p.del_flag = 0
LEFT JOIN wms_raw_material r ON g.item_type = 'raw_material' AND g.item_id = r.raw_material_id AND r.del_flag = 0
ORDER BY g.actual_warehouse_id, g.item_type, g.item_id
</select>
</mapper>