<?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：入库类型
    - projectNo：xm_no
    - projectName：MAX(xm_ms)
    - goodsCount：COUNT(*)
    过滤：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=1；xj 为空归类为“未知县局” -->
    <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=1，ly_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>


    <!-- 外层聚合到 SceneAvailableVO，并级联 positions（PcdeDetailSimpleVO 列表） -->
    <resultMap id="SceneAvailableMap"
               type="com.zg.project.wisdom.domain.vo.SceneAvailableVO">
        <result property="sceneCode"       column="sceneCode"/>
        <result property="sceneName"       column="sceneName"/>
        <result property="availableCount"  column="availableCount"/>
        <!-- 把外层 select 的 warehouseCode、sceneCode 作为参数传给内层查询 -->
        <collection property="positions"
                    ofType="com.zg.project.wisdom.domain.vo.PcdeDetailSimpleVO"
                    select="selectAvailablePositionsByWarehouseAndScene"
                    column="{warehouseCode=warehouseCode,sceneCode=sceneCode}"/>
    </resultMap>

    <!-- 外层：按场景统计可用数量（并输出 warehouseCode、sceneCode 提供给内层） -->
    <select id="selectAvailableByWarehouse" parameterType="string"
            resultMap="SceneAvailableMap">
        SELECT
            #{warehouseCode}           AS warehouseCode,  -- 传给内层用
            p.scene                    AS sceneCode,
            sm.scene_name              AS sceneName,
            COUNT(*)                   AS availableCount
        FROM pcde_detail p
                 LEFT JOIN scene_mapping sm
                           ON sm.scene_code = p.scene
                 LEFT JOIN rk_info ri
                           ON ri.pcode = p.pcode
                               AND ri.is_delete = 0
                               AND (ri.is_chuku = 0 OR ri.is_chuku IS NULL)  -- 未出库 => 占用
        WHERE p.is_delete = '0'
          AND p.warehouse = #{warehouseCode}
          AND ri.id IS NULL                                   -- 无占用 => 可用
        GROUP BY p.scene, sm.scene_name
        ORDER BY p.scene
    </select>

    <!-- 内层：指定仓库 + 场景，查询该场景的可用库位明细 -->
    <select id="selectAvailablePositionsByWarehouseAndScene"
            resultType="com.zg.project.wisdom.domain.vo.PcdeDetailSimpleVO">
        SELECT
            p.pcode,
            p.tag,
            p.encoded_id AS encodedId
        FROM pcde_detail p
                 LEFT JOIN rk_info ri
                           ON ri.pcode = p.pcode
                               AND ri.is_delete = 0
                               AND (ri.is_chuku = 0 OR ri.is_chuku IS NULL)
        WHERE p.is_delete = '0'
          AND p.warehouse = #{warehouseCode}
          AND p.scene = #{sceneCode}
          AND ri.id IS NULL
        ORDER BY p.pcode
    </select>
</mapper>
