Files
klp-oa/klp-wms/src/main/resources/mapper/klp/WmsStockMapper.xml
Joshi 51506bbb66 feat(stock): 优化实际库区查询速率使用CTE递归查询
- 修改 WmsStockMapper 接口,增加 rootWarehouseId 参数用于限定查询范围
- 优化 WmsStockMapper.xml 中的 SQL 查询逻辑,引入 CTE 递归查询子仓库数据
- 调整查询语句结构,将分组统计与关联查询分离以提升性能
- 移除 Java 层递归获取子仓库 ID 的逻辑,改为数据库端处理
- 强制使用指定索引 idx_mc_fixed_group 提高查询效率
- 更新服务实现类传参逻辑,传递实际仓库 ID 用于构建查询条件
2025-12-18 09:41:22 +08:00

155 lines
7.4 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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.klp.mapper.WmsStockMapper">
<resultMap type="com.klp.domain.WmsStock" id="WmsStockResult">
<result property="stockId" column="stock_id"/>
<result property="itemType" column="item_type"/>
<result property="itemId" column="item_id"/>
<result property="batchNo" column="batch_no"/>
<result property="remark" column="remark"/>
<result property="delFlag" column="del_flag"/>
<result property="createTime" column="create_time"/>
<result property="createBy" column="create_by"/>
<result property="updateTime" column="update_time"/>
<result property="updateBy" column="update_by"/>
</resultMap>
<select id="getStockByItemId" resultType="java.math.BigDecimal">
select sum(quantity) as quantity from wms_stock
where item_id = #{rawMaterialId} and item_type = 'raw_material' and del_flag = 0
</select>
<!-- 查询物料库存统计基于物料钢卷表支持Wrapper动态条件包含group by返回Page<WmsStockVo> -->
<select id="selectVoPagePlus" resultType="com.klp.domain.vo.WmsStockVo">
SELECT
mc.warehouse_id AS warehouseId,
mc.item_type AS itemType,
mc.item_id AS itemId,
w.warehouse_name AS warehouseName,
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,
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,
CASE
WHEN mc.item_type = 'product' THEN p.specification
WHEN mc.item_type = 'raw_material' THEN r.specification
ELSE NULL
END AS specification,
CASE
WHEN mc.item_type = 'product' THEN p.material
WHEN mc.item_type = 'raw_material' THEN r.material
ELSE NULL
END AS material,
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,
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,
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_warehouse w ON mc.warehouse_id = w.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}
</select>
<!-- 按仓库统计库存分布 -->
<select id="selectStockDistribution" resultType="com.klp.domain.vo.WmsStockVo">
SELECT
mc.warehouse_id AS warehouseId,
w.warehouse_name AS warehouseName,
COUNT(*) AS totalQuantity,
mc.item_type AS itemType,
mc.item_id AS itemId
FROM wms_material_coil mc
INNER JOIN wms_warehouse w ON mc.warehouse_id = w.warehouse_id AND w.del_flag = 0
WHERE mc.item_type = #{itemType}
AND mc.item_id = #{itemId}
AND mc.del_flag = 0
AND mc.data_type = 1
GROUP BY mc.warehouse_id, w.warehouse_name, mc.item_type, mc.item_id
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
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>