Files
smart_management_dev/src/main/resources/mybatis/wisdom/RkStatisticsMapper.xml
2025-08-26 17:01:43 +08:00

488 lines
22 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.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>