统计相关接口开发

This commit is contained in:
2025-08-26 17:01:43 +08:00
parent 7d595c1f9f
commit acf191df81
37 changed files with 1905 additions and 11 deletions

View File

@@ -0,0 +1,487 @@
<?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.zg.project.wisdom.mapper.RkStatisticsMapper">
<!-- 库龄统计未出库按项目数统计COUNT DISTINCT xm_no -->
<select id="selectAgeStats" resultType="com.zg.project.wisdom.domain.vo.RkAgeStatVO">
SELECT
/* >10 天的项目数(至少一条记录满足 >10 天的 xm_no 个数) */
COUNT(DISTINCT CASE
WHEN ri.rk_time IS NOT NULL
AND DATEDIFF(CURDATE(), DATE(ri.rk_time)) > 10
THEN ri.xm_no END) AS gt10,
/* >20 天的项目数 */
COUNT(DISTINCT CASE
WHEN ri.rk_time IS NOT NULL
AND DATEDIFF(CURDATE(), DATE(ri.rk_time)) > 20
THEN ri.xm_no END) AS gt20,
/* >30 天的项目数 */
COUNT(DISTINCT CASE
WHEN ri.rk_time IS NOT NULL
AND DATEDIFF(CURDATE(), DATE(ri.rk_time)) > 30
THEN ri.xm_no END) AS gt30
FROM rk_info ri
WHERE ri.is_delete = 0
AND (ri.is_chuku = 0 OR ri.is_chuku IS NULL)
</select>
<!--
入库类型汇总SQL
统计每种入库类型(rk_type)下:
- 项目数量去重xm_no
- 合同单价合计(sumHtDj)
- 实际入库数量合计(sumRealQty)
- 金额合计(sumAmount = ht_dj * real_qty)
条件:
- 未删除(is_delete = 0)
- 未出库(is_chuku = 0)
-->
<select id="selectRkTypeSummary" resultType="com.zg.project.wisdom.domain.vo.RkTypeSummaryVO">
SELECT
ri.rk_type AS rkType,
COUNT(DISTINCT ri.xm_no) AS projectCount,
SUM(IFNULL(ri.ht_dj, 0)) AS sumHtDj,
SUM(IFNULL(ri.real_qty, 0)) AS sumRealQty,
SUM(IFNULL(ri.ht_dj, 0) * IFNULL(ri.real_qty, 0)) AS sumAmount
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.is_chuku = 0
GROUP BY ri.rk_type
ORDER BY rkType
</select>
<!--
2) 入库类型 × 项目:统计每个项目的“条目数”
字段:
- rkType入库类型
- projectNoxm_no
- projectNameMAX(xm_ms)
- goodsCountCOUNT(*)
过滤is_delete=0 AND is_chuku=0
-->
<select id="selectProjectGoodsCountByType"
resultType="com.zg.project.wisdom.domain.vo.RkTypeProjectGoodsCountVO">
SELECT
ri.rk_type AS rkType,
ri.xm_no AS projectNo,
MAX(ri.xm_ms) AS projectName,
COUNT(*) AS goodsCount
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.is_chuku = 0
GROUP BY ri.rk_type, ri.xm_no
ORDER BY rkType, projectNo
</select>
<!-- 入库类型汇总(未出库 & 过滤 NULL/空串/“无”) -->
<select id="selectTypeSummary" resultType="com.zg.project.wisdom.domain.vo.RkSummaryVO">
SELECT
sit.type_name AS groupName,
COUNT(DISTINCT ri.xm_no) AS projectCount,
COUNT(*) AS goodsCountTotal,
COALESCE(SUM(COALESCE(ri.real_qty, 0)), 0) AS sumQty,
COALESCE(SUM(COALESCE(ri.ht_dj, 0) * COALESCE(ri.real_qty, 0)), 0) AS sumAmount
FROM rk_info ri
LEFT JOIN stock_in_type sit
ON ri.rk_type = sit.type_code
WHERE ri.is_delete = 0
AND ri.is_chuku = 0
-- 入库类型过滤:剔除 NULL / 空串 / '无'
AND ri.rk_type IS NOT NULL
AND TRIM(ri.rk_type) &lt;&gt; ''
AND ri.rk_type &lt;&gt; '无'
-- 名称做一层过滤,避免出现“无”或空的分组
AND sit.type_name IS NOT NULL
AND TRIM(sit.type_name) &lt;&gt; ''
AND sit.type_name &lt;&gt; '无'
GROUP BY sit.type_name
ORDER BY groupName
</select>
<!-- 县局汇总(未出库 & county 非空) -->
<select id="selectCountySummary" resultType="com.zg.project.wisdom.domain.vo.RkSummaryVO">
SELECT
ri.xj AS groupName, -- 县局
COUNT(DISTINCT ri.xm_no) AS projectCount, -- 项目数
COUNT(*) AS goodsCountTotal, -- 条目总数
SUM(IFNULL(ri.ht_dj, 0) * IFNULL(ri.real_qty, 0)) AS sumAmount -- 总金额
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.is_chuku = 0
AND ri.xj IS NOT NULL
AND TRIM(ri.xj) &lt;&gt; ''
GROUP BY ri.xj
ORDER BY groupName
</select>
<!-- 入库(整段时间 + 县局rk_time 在区间内xj 为空归类为“未知县局” -->
<select id="selectWeekDailyIn" resultType="com.zg.project.wisdom.domain.vo.DayCountyStatVO">
SELECT
COALESCE(NULLIF(TRIM(ri.xj), ''), '未知县局') AS xj,
COUNT(DISTINCT ri.xm_no) AS projectCount,
COUNT(*) AS itemCount,
SUM(COALESCE(ri.real_qty, 0)) AS totalQty,
SUM(COALESCE(ri.ht_dj, 0) * COALESCE(ri.real_qty, 0)) AS amountHt,
SUM(COALESCE(ri.jh_amt, 0)) AS amountPlan
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.rk_time BETWEEN #{startDate} AND #{endDate}
GROUP BY COALESCE(NULLIF(TRIM(ri.xj), ''), '未知县局')
ORDER BY xj
</select>
<!-- 出库(整段时间 + 县局ly_time 在区间内;只统计已出库 is_chuku=1xj 为空归类为“未知县局” -->
<select id="selectWeekDailyOut" resultType="com.zg.project.wisdom.domain.vo.DayCountyStatVO">
SELECT
COALESCE(NULLIF(TRIM(ri.xj), ''), '未知县局') AS xj,
COUNT(DISTINCT ri.xm_no) AS projectCount,
COUNT(*) AS itemCount,
SUM(COALESCE(ri.real_qty, 0)) AS totalQty,
SUM(COALESCE(ri.ht_dj, 0) * COALESCE(ri.real_qty, 0)) AS amountHt,
0 AS amountPlan
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.is_chuku = 1
AND ri.ly_time BETWEEN #{startDate} AND #{endDate}
GROUP BY COALESCE(NULLIF(TRIM(ri.xj), ''), '未知县局')
ORDER BY xj
</select>
<!-- ======================
结果映射:汇总 AgeSummaryVO
====================== -->
<resultMap id="AgeSummaryMap" type="com.zg.project.wisdom.domain.vo.AgeSummaryVO">
<!-- 通过两个 association 绑定到内部 Slot 对象 -->
<association property="gt30" javaType="com.zg.project.wisdom.domain.vo.AgeSummaryVO$Slot">
<id property="dummyId" column="gt30_dummy_id"/>
<result property="projectCount" column="gt30ProjectCount"/>
<result property="goodsCount" column="gt30GoodsCount"/>
<result property="sumAmount" column="gt30Amount"/>
</association>
<association property="gt60" javaType="com.zg.project.wisdom.domain.vo.AgeSummaryVO$Slot">
<id property="dummyId" column="gt60_dummy_id"/>
<result property="projectCount" column="gt60ProjectCount"/>
<result property="goodsCount" column="gt60GoodsCount"/>
<result property="sumAmount" column="gt60Amount"/>
</association>
</resultMap>
<!-- 汇总查询:>30 / >60 的项目数、条目数、总金额 -->
<select id="selectAge3060Summary" resultMap="AgeSummaryMap">
SELECT
1 AS gt30_dummy_id,
(SELECT COUNT(DISTINCT ri.xm_no)
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.is_chuku = 0
AND ri.rk_time IS NOT NULL
AND DATEDIFF(CURDATE(), ri.rk_time) > 30) AS gt30ProjectCount,
(SELECT COUNT(*)
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.is_chuku = 0
AND ri.rk_time IS NOT NULL
AND DATEDIFF(CURDATE(), ri.rk_time) > 30) AS gt30GoodsCount,
(SELECT SUM(IFNULL(ri.ht_dj, 0) * IFNULL(ri.real_qty, 0))
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.is_chuku = 0
AND ri.rk_time IS NOT NULL
AND DATEDIFF(CURDATE(), ri.rk_time) > 30) AS gt30Amount,
1 AS gt60_dummy_id,
(SELECT COUNT(DISTINCT ri.xm_no)
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.is_chuku = 0
AND ri.rk_time IS NOT NULL
AND DATEDIFF(CURDATE(), ri.rk_time) > 60) AS gt60ProjectCount,
(SELECT COUNT(*)
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.is_chuku = 0
AND ri.rk_time IS NOT NULL
AND DATEDIFF(CURDATE(), ri.rk_time) > 60) AS gt60GoodsCount,
(SELECT SUM(IFNULL(ri.ht_dj, 0) * IFNULL(ri.real_qty, 0))
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.is_chuku = 0
AND ri.rk_time IS NOT NULL
AND DATEDIFF(CURDATE(), ri.rk_time) > 60) AS gt60Amount
FROM dual
</select>
<!-- ======================
结果映射:明细 RkAgeDetailVO
====================== -->
<resultMap id="RkAgeDetailMap" type="com.zg.project.wisdom.domain.vo.RkAgeDetailVO">
<id property="id" column="id"/>
<result property="xmNo" column="xmNo"/>
<result property="xmMs" column="xmMs"/>
<result property="rkTime" column="rkTime"/>
<result property="kuLingDays" column="kuLingDays"/>
<result property="htDj" column="htDj"/>
<result property="realQty" column="realQty"/>
<result property="amount" column="amount"/>
<result property="pcode" column="pcode"/>
<result property="trayCode" column="trayCode"/>
<result property="billNo" column="billNo"/>
</resultMap>
<!-- 明细查询:超过 minDays 天的所有未出库记录 -->
<select id="selectAgeDetails" parameterType="int" resultMap="RkAgeDetailMap">
SELECT
ri.id,
ri.xm_no AS xmNo,
ri.xm_ms AS xmMs,
ri.rk_time AS rkTime,
DATEDIFF(CURDATE(), ri.rk_time) AS kuLingDays,
ri.ht_dj AS htDj,
ri.real_qty AS realQty,
IFNULL(ri.ht_dj, 0) * IFNULL(ri.real_qty, 0) AS amount,
ri.pcode AS pcode,
ri.tray_code AS trayCode,
ri.bill_no AS billNo
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.is_chuku = 0
AND ri.rk_time IS NOT NULL
AND DATEDIFF(CURDATE(), ri.rk_time) > #{minDays}
ORDER BY ri.rk_time ASC
</select>
<resultMap id="RkTypePieMap" type="com.zg.project.wisdom.domain.vo.RkTypePieVO">
<result property="rkTypeCode" column="rkTypeCode"/> <!-- 类型编码 -->
<result property="rkTypeName" column="rkTypeName"/> <!-- 类型名称 -->
<result property="projectCount" column="projectCount"/> <!-- 项目数 -->
<result property="goodsCountTotal" column="goodsCountTotal"/> <!-- 条目总数 -->
<result property="sumQty" column="sumQty"/> <!-- 总数量 -->
<result property="sumAmount" column="sumAmount"/> <!-- 总金额 -->
</resultMap>
<!-- 入库类型饼图统计(联查 stock_in_type未删除 + 未出库rk_type 非空) -->
<select id="selectTypePie" resultMap="RkTypePieMap">
SELECT
COALESCE(sit.type_code, ri.rk_type) AS rkTypeCode,
COALESCE(sit.type_name, ri.rk_type) AS rkTypeName,
COUNT(DISTINCT ri.xm_no) AS projectCount,
COUNT(*) AS goodsCountTotal,
SUM(IFNULL(ri.real_qty, 0)) AS sumQty,
SUM(IFNULL(ri.ht_dj, 0) * IFNULL(ri.real_qty, 0)) AS sumAmount
FROM rk_info ri
LEFT JOIN stock_in_type sit
ON ri.rk_type = sit.type_code
WHERE ri.is_delete = 0
AND ri.is_chuku = 0
AND ri.rk_type IS NOT NULL
AND TRIM(ri.rk_type) != ''
GROUP BY COALESCE(sit.type_code, ri.rk_type),
COALESCE(sit.type_name, ri.rk_type)
ORDER BY sumAmount DESC
</select>
<!-- 按入库类型统计(时间范围;只统计类型有效,过滤 NULL/空/“无”) -->
<select id="selectTypeSummaryByRange" resultMap="RkTypePieMap">
<![CDATA[
SELECT
COALESCE(sit.type_code, ri.rk_type) AS rkTypeCode,
COALESCE(sit.type_name, ri.rk_type) AS rkTypeName,
COUNT(DISTINCT ri.xm_no) AS projectCount,
COUNT(*) AS goodsCountTotal,
COALESCE(SUM(COALESCE(ri.real_qty, 0)), 0) AS sumQty,
COALESCE(SUM(COALESCE(ri.ht_dj, 0) * COALESCE(ri.real_qty, 0)), 0) AS sumAmount
FROM rk_info ri
LEFT JOIN stock_in_type sit
ON ri.rk_type = sit.type_code
WHERE ri.is_delete = 0
AND (ri.is_chuku = 0 OR ri.is_chuku IS NULL) -- 当前库存口径(保持你原条件)
-- 入库类型过滤:剔除 NULL / 空串 / '无'
AND ri.rk_type IS NOT NULL
AND TRIM(ri.rk_type) <> ''
AND ri.rk_type <> '无'
-- 若字典表匹配到了名称且名称为“无”,也剔除;未匹配(NULL)则保留
AND (sit.type_name IS NULL OR (TRIM(sit.type_name) <> '' AND sit.type_name <> '无'))
-- 时间范围:闭区间 [start, end]
AND ri.rk_time >= #{start}
AND ri.rk_time < DATE_ADD(#{end}, INTERVAL 1 DAY)
GROUP BY COALESCE(sit.type_code, ri.rk_type), COALESCE(sit.type_name, ri.rk_type)
ORDER BY sumAmount DESC
]]>
</select>
<select id="selectOutTypeSummaryByRange"
resultType="com.zg.project.wisdom.domain.vo.RkTypePieVO">
<![CDATA[
SELECT
COALESCE(sot.type_code, ri.ck_type) AS rkTypeCode,
COALESCE(sot.type_name, ri.ck_type) AS rkTypeName,
COUNT(DISTINCT COALESCE(NULLIF(TRIM(ri.xm_no_ck), ''), ri.xm_no)) AS projectCount,
COUNT(*) AS goodsCountTotal,
SUM(IFNULL(ri.real_qty, 0)) AS sumQty,
SUM(IFNULL(ri.ht_dj, 0) * IFNULL(ri.real_qty, 0)) AS sumAmount
FROM rk_info ri
LEFT JOIN stock_out_type sot ON ri.ck_type = sot.type_code
WHERE ri.is_delete = 0
AND ri.is_chuku = 1
-- 过滤出库类型为 NULL / 空串 / '无'
AND ri.ck_type IS NOT NULL
AND TRIM(ri.ck_type) <> ''
AND ri.ck_type <> '无'
AND (sot.type_name IS NULL OR TRIM(sot.type_name) <> '无')
-- 时间范围:闭区间 [start, end]
AND ri.ly_time >= #{start}
AND ri.ly_time < DATE_ADD(#{end}, INTERVAL 1 DAY)
GROUP BY COALESCE(sot.type_code, ri.ck_type), COALESCE(sot.type_name, ri.ck_type)
ORDER BY sumAmount DESC
]]>
</select>
<!-- 入库rk_time 在区间内(不限制是否已出库,统计本月入库流水) -->
<select id="selectMonthlyInSummary" resultType="com.zg.project.wisdom.domain.vo.RkMonthSummaryVO">
SELECT
COUNT(DISTINCT ri.xm_no) AS projectCount,
COUNT(*) AS itemCount,
SUM(COALESCE(ri.real_qty, 0)) AS totalQty,
SUM(COALESCE(ri.ht_dj, 0) * COALESCE(ri.real_qty, 0)) AS amountHt
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.rk_time &gt;= #{start}
AND ri.rk_time &lt; #{end}
</select>
<!-- 出库is_chuku=1ly_time 在区间内 -->
<select id="selectMonthlyOutSummary" resultType="com.zg.project.wisdom.domain.vo.RkMonthSummaryVO">
SELECT
COUNT(DISTINCT ri.xm_no) AS projectCount,
COUNT(*) AS itemCount,
SUM(COALESCE(ri.real_qty, 0)) AS totalQty,
SUM(COALESCE(ri.ht_dj, 0) * COALESCE(ri.real_qty, 0)) AS amountHt
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.is_chuku = 1
AND ri.ly_time IS NOT NULL
AND ri.ly_time &gt;= #{start}
AND ri.ly_time &lt; #{end}
</select>
<!-- 未到货status='0' -->
<select id="selectUndelivered" resultType="com.zg.project.wisdom.domain.vo.GysJhUndeliveredSummaryVO">
SELECT
COUNT(DISTINCT jh.xm_no) AS projectCount,
COUNT(*) AS itemCount,
SUM(COALESCE(jh.jh_qty, 0)) AS totalQty,
/* 金额 = 有效单价 × 剩余未到数量jh_qty */
SUM(
COALESCE(
NULLIF(jh.ht_dj, 0),
CASE WHEN COALESCE(jh.ht_qty, 0) > 0
THEN jh.jh_amt / jh.ht_qty
ELSE 0
END
) * COALESCE(jh.jh_qty, 0)
) AS amountPlan
FROM gys_jh jh
WHERE jh.is_delete = '0'
AND jh.status = '0'
</select>
<!-- 部分未到status='2' -->
<select id="selectPartialUndelivered" resultType="com.zg.project.wisdom.domain.vo.GysJhUndeliveredSummaryVO">
SELECT
COUNT(DISTINCT jh.xm_no) AS projectCount,
COUNT(*) AS itemCount,
SUM(COALESCE(jh.jh_qty, 0)) AS totalQty,
SUM(
COALESCE(
NULLIF(jh.ht_dj, 0),
CASE WHEN COALESCE(jh.ht_qty, 0) > 0
THEN jh.jh_amt / jh.ht_qty
ELSE 0
END
) * COALESCE(jh.jh_qty, 0)
) AS amountPlan
FROM gys_jh jh
WHERE jh.is_delete = '0'
AND jh.status = '2'
</select>
<!-- 当前库存:按物资类型统计
- 仅统计未出库is_chuku = 0 或 NULL
- 仅统计未删除is_delete = 0
- 过滤 wl_type 为空/空白/'无'
-->
<select id="selectCurrentStockByWlType"
resultType="com.zg.project.wisdom.domain.vo.WlTypeStockStatVO">
SELECT
mt.type_name AS typeName,
COUNT(DISTINCT ri.xm_no) AS projectCount,
COUNT(*) AS itemCount,
COALESCE(SUM(COALESCE(ri.real_qty, 0)), 0) AS totalQty,
COALESCE(SUM(COALESCE(ri.ht_dj, 0) * COALESCE(ri.real_qty, 0)), 0) AS amountHt
FROM rk_info ri
JOIN material_type mt
ON mt.type_code = ri.wl_type
AND mt.status = 1
WHERE ri.is_delete = 0
AND (ri.is_chuku = 0 OR ri.is_chuku IS NULL)
AND ri.wl_type IS NOT NULL
AND TRIM(ri.wl_type) != ''
AND ri.wl_type != '无'
AND mt.type_name != '无'
GROUP BY mt.type_code, mt.type_name
ORDER BY amountHt DESC
</select>
<!-- 当前库存:入库时间 > 30 天(仅未出库 & 未删除 & rk_time 非空) -->
<select id="selectAgeGt30Summary"
resultType="com.zg.project.wisdom.domain.vo.RkTypePieVO">
SELECT
COUNT(DISTINCT ri.xm_no) AS projectCount, -- 去重项目数
COUNT(*) AS goodsCountTotal, -- 条目数
COALESCE(SUM(COALESCE(ri.real_qty, 0)), 0) AS sumQty, -- 数量合计
COALESCE(SUM(COALESCE(ri.ht_dj, 0) * COALESCE(ri.real_qty, 0)), 0) AS sumAmount -- 金额合计
FROM rk_info ri
WHERE ri.is_delete = 0
AND (ri.is_chuku = 0 OR ri.is_chuku IS NULL)
AND ri.rk_time IS NOT NULL
AND DATEDIFF(CURDATE(), DATE(ri.rk_time)) > 30
</select>
<!-- 入库原始行 -->
<select id="selectInRange" resultType="com.zg.project.wisdom.domain.vo.RkInVO">
SELECT
ri.xm_no AS xmNo,
ri.rk_time AS rkTime
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.rk_time IS NOT NULL
AND ri.rk_time <![CDATA[>=]]> #{startTs}
AND ri.rk_time <![CDATA[<]]> #{endTs}
</select>
<!-- 出库原始行(有效时间=ly_time 优先,否则 update_time项目号=xm_no_ck 优先,否则 xm_no -->
<select id="selectOutRange" resultType="com.zg.project.wisdom.domain.vo.RkOutVO">
SELECT
ri.xm_no_ck AS xmNoCk,
ri.xm_no AS xmNo,
ri.ly_time AS lyTime,
ri.update_time AS updateTime
FROM rk_info ri
WHERE ri.is_delete = 0
AND ri.is_chuku = 1
AND (
(ri.ly_time IS NOT NULL
AND ri.ly_time <![CDATA[>=]]> #{startTs}
AND ri.ly_time <![CDATA[<]]> #{endTs})
OR (ri.ly_time IS NULL AND ri.update_time IS NOT NULL
AND ri.update_time <![CDATA[>=]]> #{startTs}
AND ri.update_time <![CDATA[<]]> #{endTs})
)
</select>
</mapper>

View File

@@ -0,0 +1,50 @@
<?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.zg.project.wisdom.mapper.WarehouseStatMapper">
<!-- 1) 启用仓库列表 -->
<resultMap id="WarehouseLiteMap" type="com.zg.project.wisdom.domain.vo.WarehouseStatVO">
<result property="warehouseCode" column="warehouse_code"/>
<result property="warehouseName" column="warehouse_name"/>
</resultMap>
<select id="selectEnabledWarehouses" resultMap="WarehouseLiteMap">
SELECT wi.warehouse_code, wi.warehouse_name
FROM warehouse_info wi
WHERE wi.status = 1
ORDER BY wi.warehouse_code
</select>
<!-- 2) 指定仓库的场景库位统计(总库位/已使用) -->
<resultMap id="SceneUsageMap" type="com.zg.project.wisdom.domain.vo.SceneUsageVO">
<result property="sceneCode" column="scene_code"/>
<result property="sceneName" column="scene_name"/>
<result property="totalPositions" column="total_positions"/>
<result property="usedPositions" column="used_positions"/>
</resultMap>
<select id="selectSceneUsageByWarehouse" resultMap="SceneUsageMap">
SELECT
sm.scene_code,
sm.scene_name,
COUNT(DISTINCT pd.pcode) AS total_positions,
COUNT(DISTINCT CASE WHEN ri.is_chuku = 0 THEN pd.pcode END) AS used_positions
FROM pcde_detail pd
LEFT JOIN scene_mapping sm
ON pd.scene = sm.scene_code
LEFT JOIN rk_info ri
ON pd.pcode = ri.pcode
WHERE pd.warehouse = #{warehouseCode}
AND (pd.is_delete IS NULL OR pd.is_delete = 0)
GROUP BY sm.scene_code, sm.scene_name
ORDER BY sm.scene_code
</select>
<!-- 3) 启用仓库总数 -->
<select id="countEnabledWarehouses" resultType="int">
SELECT COUNT(*) FROM warehouse_info wi WHERE wi.status = 1
</select>
</mapper>