chengf
2025-08-26 ace8009da36d622f72e4145eb0b38f0a344f3a45
java110-db/src/main/resources/mapper/fee/ReportFeeServiceDaoImplMapper.xml
@@ -259,130 +259,208 @@
        </if>
    </select>
    <select id="sss">
    <select id="onceRoomFee">
        WITH year_series AS (
            -- 生成2016-2025年序列(独立CTE便于复用)
            -- 生成2016-2025年完整年份序列
            SELECT 2016 + n AS year
            FROM (
                     SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                     UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
                 ) AS nums
        ),
             all_data AS (
             base_data AS (
                 -- 基础数据:仅保留确认存在的核心字段
                 SELECT
                     pf.fee_id AS 费用编号,
                     pfc.fee_name AS 费用名称,
                     ys.year AS 年份,
                     -- 计算当年有效时间范围(1月1日至12月31日)
                     STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d') AS 当年起始日,
                     STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d') AS 当年截止日,
                     -- 已收区间(严格限定在当年范围内)
                     CASE
                         -- 费用起始时间晚于当年年底:无已收
                         WHEN pf.start_time > STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d') THEN NULL
                         -- 费用截止时间早于当年年初:无已收
                         WHEN pf.end_time &lt; STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d') THEN NULL
                         -- 正常情况:取重叠区间
                         ELSE GREATEST(pf.start_time, STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d'))
                         END AS 当年已收起始日,
                     CASE
                         WHEN pf.start_time > STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d') THEN NULL
                         WHEN pf.end_time &lt; STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d') THEN NULL
                         ELSE LEAST(pf.end_time, STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d'))
                         END AS 当年已收截止日,
                     -- 未收区间(严格限定在当年范围内)
                     CASE
                         -- 应缴截止时间早于当年年初:无未收
                         WHEN STR_TO_DATE(pfa.`value`, '%Y-%m-%d') &lt; STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d') THEN NULL
                         -- 费用截止时间晚于当年年底:无未收
                         WHEN pf.end_time > STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d') THEN NULL
                         -- 正常情况:取重叠区间
                         ELSE GREATEST(pf.end_time, STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d'))
                         END AS 当年未收起始日,
                     CASE
                         WHEN STR_TO_DATE(pfa.`value`, '%Y-%m-%d') &lt; STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d') THEN NULL
                         WHEN pf.end_time > STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d') THEN NULL
                         ELSE LEAST(STR_TO_DATE(pfa.`value`, '%Y-%m-%d'), STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d'))
                         END AS 当年未收截止日,
                     -- 已收月数(仅统计当年的有效明细)
                     COALESCE(COUNT(DISTINCT CASE
                                                 WHEN pfdm.detail_year = ys.year AND pfdm.status_cd = '0'
                                                     THEN CONCAT(pfdm.detail_year, '-', LPAD(pfdm.detail_month, 2, '0'))
                         END), 0) AS 当年已收月数,
                     -- 应收月数(当年内的理论应收月数)
                     CASE
                         WHEN GREATEST(pf.start_time, STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d')) >
                              LEAST(STR_TO_DATE(pfa.`value`, '%Y-%m-%d'), STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d'))
                             THEN 0
                         ELSE TIMESTAMPDIFF(
                                      MONTH,
                                      GREATEST(pf.start_time, STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d')),
                                      LEAST(STR_TO_DATE(pfa.`value`, '%Y-%m-%d'), STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d'))
                              ) + 1
                         END AS 当年应收月数,
                     -- 计算每月费用(单价×面积)
                     pfc.square_price * br.built_up_area AS 每月费用,
                     -- 折扣金额(仅统计当年的有效折扣)
                     COALESCE(SUM(CASE WHEN pfdm.detail_year = ys.year THEN pfdm.discount_amount ELSE 0 END), 0) AS 当年折扣金额
                     pfc.fee_type_cd AS 费用类型编码,
                     pf.payer_obj_id AS 房屋ID,
                     pf.start_time AS 费用起始时间,
                     pf.end_time AS 费用截止时间,
                     STR_TO_DATE(pfa.`value`, '%Y-%m-%d') AS 应缴截止日期,
                     pfc.square_price AS 单价,
                     br.built_up_area AS 建筑面积,
                     pfc.square_price * br.built_up_area AS 每月费用标准,
                     ys.year AS 统计年份,
                     STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d') AS 当年1月1日,
                     STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d') AS 当年12月31日
                 FROM pay_fee pf
                          INNER JOIN pay_fee_config pfc
                                     ON pf.config_id = pfc.config_id
                                         AND pfc.square_price > 0  -- 确保有有效单价
                                         AND pfc.square_price > 0
                          INNER JOIN building_room br
                                     ON pf.payer_obj_id = br.room_id
                          INNER JOIN pay_fee_attrs pfa
                                     ON pf.fee_id = pfa.fee_id
                                         AND pfa.spec_cd = '390010'  -- 应缴截止日期属性
                          INNER JOIN year_series ys ON 1=1  -- 关联年份序列
                          LEFT JOIN pay_fee_detail_month pfdm
                                    ON pf.fee_id = pfdm.fee_id
                                        AND pfdm.obj_id = pf.payer_obj_id
                                        AND pfdm.status_cd = '0'  -- 有效明细
                 WHERE pf.payer_obj_id = '752025071562520009'
                                         AND pfa.spec_cd = '390010'
                          INNER JOIN year_series ys ON 1=1
                 WHERE pf.payer_obj_id = #{payObjId}
                   AND pf.fee_type_cd IN ('630000001', '630000002')
                   AND pf.status_cd = '0'  -- 有效费用
                 GROUP BY
                     pf.fee_id, pfc.fee_name, ys.year,
                     pf.start_time, pf.end_time, pfa.`value`,
                     pfc.square_price, br.built_up_area
                   AND pf.status_cd = '0'
             ),
             detail_agg AS (
                 -- 明细汇总:核心修正→已收月数/金额仅统计received_amount>0的记录
                 SELECT
                     bd.费用编号,
                     bd.统计年份,
                     COUNT(DISTINCT CASE
                                        WHEN pfdm.detail_year = bd.统计年份
                                            AND pfdm.status_cd = '0'
                                            AND pfdm.received_amount > 0
                                            THEN CONCAT(pfdm.detail_year, '-', LPAD(pfdm.detail_month, 2, '0'))
                         END) AS 当年已收月数,
                     SUM(CASE
                             WHEN pfdm.detail_year = bd.统计年份
                                 AND pfdm.status_cd = '0'
                                 AND pfdm.received_amount > 0
                                 THEN pfdm.received_amount
                             ELSE 0
                         END) AS 当年实收金额,
                     SUM(CASE
                             WHEN pfdm.detail_year = bd.统计年份
                                 AND pfdm.status_cd = '0'
                                 AND pfdm.received_amount > 0
                                 THEN pfdm.discount_amount
                             ELSE 0
                         END) AS 当年折扣金额
                 FROM base_data bd
                          LEFT JOIN pay_fee_detail_month pfdm
                                    ON bd.费用编号 = pfdm.fee_id
                                        AND pfdm.obj_id = bd.房屋ID
                 GROUP BY bd.费用编号, bd.统计年份
             ),
             calculated_data AS (
                 -- 计算金额字段(基于已收/应收月数)
                 -- 计算衍生字段:应收月数、区间等
                 SELECT
                     费用编号,
                     费用名称,
                     年份,
                     当年已收起始日,
                     当年已收截止日,
                     当年未收起始日,
                     当年未收截止日,
                     当年已收月数,
                     当年应收月数,
                     每月费用,
                     当年折扣金额,
                     -- 应收金额=应收月数×每月费用
                     当年应收月数 * 每月费用 AS 当年应收金额,
                     -- 实收金额=已收月数×每月费用-折扣金额
                     (当年已收月数 * 每月费用) - 当年折扣金额 AS 当年实收金额
                 FROM all_data
                     bd.费用编号,
                     bd.费用名称,
                     bd.费用类型编码,
                     bd.房屋ID,
                     bd.统计年份,
                     bd.每月费用标准,
                     -- 应收月数
                     CASE
                         WHEN GREATEST(bd.费用起始时间, bd.当年1月1日) >
                              LEAST(bd.应缴截止日期, bd.当年12月31日)
                             THEN 0
                         ELSE TIMESTAMPDIFF(
                                      MONTH,
                                      GREATEST(bd.费用起始时间, bd.当年1月1日),
                                      LEAST(bd.应缴截止日期, bd.当年12月31日)
                              ) + 1
                         END AS 当年应收月数,
                     -- 应收金额
                     (CASE
                          WHEN GREATEST(bd.费用起始时间, bd.当年1月1日) >
                               LEAST(bd.应缴截止日期, bd.当年12月31日)
                              THEN 0
                          ELSE TIMESTAMPDIFF(
                                       MONTH,
                                       GREATEST(bd.费用起始时间, bd.当年1月1日),
                                       LEAST(bd.应缴截止日期, bd.当年12月31日)
                               ) + 1
                         END) * bd.每月费用标准 AS 当年应收金额,
                     -- 已收区间起始/截止日
                     CASE
                         WHEN bd.费用起始时间 > bd.当年12月31日 THEN NULL
                         WHEN bd.费用截止时间 &lt; bd.当年1月1日 THEN NULL
                         ELSE GREATEST(bd.费用起始时间, bd.当年1月1日)
                         END AS 当年已收起始日,
                     CASE
                         WHEN bd.费用起始时间 > bd.当年12月31日 THEN NULL
                         WHEN bd.费用截止时间 &lt; bd.当年1月1日 THEN NULL
                         ELSE LEAST(bd.费用截止时间, bd.当年12月31日)
                         END AS 当年已收截止日,
                     -- 未收区间起始/截止日
                     CASE
                         WHEN bd.应缴截止日期 &lt; bd.当年1月1日 THEN NULL
                         WHEN bd.费用截止时间 > bd.当年12月31日 THEN NULL
                         ELSE GREATEST(bd.费用截止时间, bd.当年1月1日)
                         END AS 当年未收起始日,
                     CASE
                         WHEN bd.应缴截止日期 &lt; bd.当年1月1日 THEN NULL
                         WHEN bd.费用截止时间 > bd.当年12月31日 THEN NULL
                         ELSE LEAST(bd.应缴截止日期, bd.当年12月31日)
                         END AS 当年未收截止日,
                     -- 明细数据
                     COALESCE(da.当年已收月数, 0) AS 当年已收月数,
                     COALESCE(da.当年实收金额, 0) AS 当年实收金额,
                     COALESCE(da.当年折扣金额, 0) AS 当年折扣金额,
                     -- 应收区间相关计算字段
                     GREATEST(bd.费用起始时间, bd.当年1月1日) AS 原始应收起始日,
                     LEAST(bd.应缴截止日期, bd.当年12月31日) AS 原始应收截止日,
                     bd.当年12月31日 AS 当年年末日,
                     -- 原始应收区间
                     CASE
                         WHEN GREATEST(bd.费用起始时间, bd.当年1月1日) &lt;=
                              LEAST(bd.应缴截止日期, bd.当年12月31日)
                             THEN CONCAT(
                                 DATE_FORMAT(GREATEST(bd.费用起始时间, bd.当年1月1日), '%Y-%m-%d'),
                                 ' ~ ',
                                 DATE_FORMAT(LEAST(bd.应缴截止日期, bd.当年12月31日), '%Y-%m-%d')
                                  )
                         ELSE NULL
                         END AS 原始应收区间,
                     -- 补充应收区间
                     CASE
                         WHEN (GREATEST(bd.费用起始时间, bd.当年1月1日) >
                               LEAST(bd.应缴截止日期, bd.当年12月31日))
                             AND (CASE
                                      WHEN GREATEST(bd.费用起始时间, bd.当年1月1日) >
                                           LEAST(bd.应缴截止日期, bd.当年12月31日)
                                          THEN 0
                                      ELSE TIMESTAMPDIFF(
                                                   MONTH,
                                                   GREATEST(bd.费用起始时间, bd.当年1月1日),
                                                   LEAST(bd.应缴截止日期, bd.当年12月31日)
                                           ) + 1
                                 END) > 0
                             THEN CONCAT(
                                 DATE_FORMAT(DATE_SUB(bd.当年12月31日, INTERVAL (CASE
                                                                                     WHEN GREATEST(bd.费用起始时间, bd.当年1月1日) >
                                                                                          LEAST(bd.应缴截止日期, bd.当年12月31日)
                                                                                         THEN 0
                                                                                     ELSE TIMESTAMPDIFF(
                                                                                                  MONTH,
                                                                                                  GREATEST(bd.费用起始时间, bd.当年1月1日),
                                                                                                  LEAST(bd.应缴截止日期, bd.当年12月31日)
                                                                                          ) + 1
                                     END) - 1 MONTH), '%Y-%m-%d'),
                                 ' ~ ',
                                 DATE_FORMAT(bd.当年12月31日, '%Y-%m-%d')
                                  )
                         ELSE NULL
                         END AS 补充应收区间
                 FROM base_data bd
                          LEFT JOIN detail_agg da
                                    ON bd.费用编号 = da.费用编号
                                        AND bd.统计年份 = da.统计年份
             ),
             grouped_data AS (
                 -- 各年份数据
                 -- 1. 各年份明细数据
                 SELECT
                     费用编号,
                     费用名称,
                     CONCAT(年份, '年') AS 统计维度,
                     年份 AS 排序辅助,
                     费用类型编码,
                     房屋ID,
                     CONCAT(统计年份, '年') AS 统计维度,
                     统计年份 AS 排序辅助,
                     当年应收月数 AS 应收月数,
                     当年已收月数 AS 已收月数,
                     -- 已收区间(仅显示有效区间)
                     CASE
                         WHEN 原始应收区间 IS NOT NULL THEN 原始应收区间
                         WHEN 当年应收月数 > 0 THEN 补充应收区间
                         ELSE NULL
                         END AS 应收区间,
                     CASE
                         WHEN 当年已收起始日 IS NOT NULL AND 当年已收截止日 IS NOT NULL
                             AND 当年已收月数 > 0
                             THEN CONCAT(DATE_FORMAT(当年已收起始日, '%Y-%m-%d'), ' ~ ', DATE_FORMAT(当年已收截止日, '%Y-%m-%d'))
                         ELSE NULL
                         END AS 已收区间,
                     -- 未收区间(仅显示有效区间)
                     CASE
                         WHEN 当年未收起始日 IS NOT NULL AND 当年未收截止日 IS NOT NULL
                             AND 当年应收月数 > 当年已收月数
                             THEN CONCAT(DATE_FORMAT(当年未收起始日, '%Y-%m-%d'), ' ~ ', DATE_FORMAT(当年未收截止日, '%Y-%m-%d'))
                         ELSE NULL
                         END AS 未收区间,
@@ -390,24 +468,43 @@
                     当年实收金额 AS 实收金额,
                     当年折扣金额 AS 折扣金额
                 FROM calculated_data
                 WHERE 年份 BETWEEN 2016 AND 2025
                 WHERE 统计年份 BETWEEN 2016 AND 2025
                 UNION ALL
                 -- 2020年单独统计
                 -- 2. 2020年单独汇总
                 SELECT
                     费用编号,
                     费用名称,
                     费用类型编码,
                     房屋ID,
                     '2020年' AS 统计维度,
                     2020 AS 排序辅助,
                     SUM(当年应收月数) AS 应收月数,
                     SUM(当年已收月数) AS 已收月数,
                     CASE
                         WHEN SUM(当年应收月数) > 0 THEN CONCAT(
                                 DATE_FORMAT(MIN(CASE
                                                     WHEN 原始应收起始日 &lt;= 原始应收截止日 THEN 原始应收起始日
                                                     ELSE DATE_SUB(当年年末日, INTERVAL (当年应收月数 - 1) MONTH)
                                     END), '%Y-%m-%d'),
                                 ' ~ ',
                                 DATE_FORMAT(MAX(CASE
                                                     WHEN 原始应收起始日 &lt;= 原始应收截止日 THEN 原始应收截止日
                                                     ELSE 当年年末日
                                     END), '%Y-%m-%d')
                                                         )
                         ELSE NULL
                         END AS 应收区间,
                     CASE
                         WHEN MIN(当年已收起始日) IS NOT NULL AND MAX(当年已收截止日) IS NOT NULL
                             AND SUM(当年已收月数) > 0
                             THEN CONCAT(DATE_FORMAT(MIN(当年已收起始日), '%Y-%m-%d'), ' ~ ', DATE_FORMAT(MAX(当年已收截止日), '%Y-%m-%d'))
                         ELSE NULL
                         END AS 已收区间,
                     CASE
                         WHEN MIN(当年未收起始日) IS NOT NULL AND MAX(当年未收截止日) IS NOT NULL
                             AND SUM(当年应收月数) > SUM(当年已收月数)
                             THEN CONCAT(DATE_FORMAT(MIN(当年未收起始日), '%Y-%m-%d'), ' ~ ', DATE_FORMAT(MAX(当年未收截止日), '%Y-%m-%d'))
                         ELSE NULL
                         END AS 未收区间,
@@ -415,25 +512,44 @@
                     SUM(当年实收金额) AS 实收金额,
                     SUM(当年折扣金额) AS 折扣金额
                 FROM calculated_data
                 WHERE 年份 = 2020
                 GROUP BY 费用编号, 费用名称, 统计维度, 排序辅助
                 WHERE 统计年份 = 2020
                 GROUP BY 费用编号, 费用名称, 费用类型编码, 房屋ID, 统计维度, 排序辅助
                 UNION ALL
                 -- 2016-2025年合计
                 -- 3. 2016-2025年合计
                 SELECT
                     费用编号,
                     费用名称,
                     费用类型编码,
                     房屋ID,
                     '2016-2025年合计' AS 统计维度,
                     9999 AS 排序辅助,
                     SUM(当年应收月数) AS 应收月数,
                     SUM(当年已收月数) AS 已收月数,
                     CASE
                         WHEN SUM(当年应收月数) > 0 THEN CONCAT(
                                 DATE_FORMAT(MIN(CASE
                                                     WHEN 原始应收起始日 &lt;= 原始应收截止日 THEN 原始应收起始日
                                                     ELSE DATE_SUB(当年年末日, INTERVAL (当年应收月数 - 1) MONTH)
                                     END), '%Y-%m-%d'),
                                 ' ~ ',
                                 DATE_FORMAT(MAX(CASE
                                                     WHEN 原始应收起始日 &lt;= 原始应收截止日 THEN 原始应收截止日
                                                     ELSE 当年年末日
                                     END), '%Y-%m-%d')
                                                         )
                         ELSE NULL
                         END AS 应收区间,
                     CASE
                         WHEN MIN(当年已收起始日) IS NOT NULL AND MAX(当年已收截止日) IS NOT NULL
                             AND SUM(当年已收月数) > 0
                             THEN CONCAT(DATE_FORMAT(MIN(当年已收起始日), '%Y-%m-%d'), ' ~ ', DATE_FORMAT(MAX(当年已收截止日), '%Y-%m-%d'))
                         ELSE NULL
                         END AS 已收区间,
                     CASE
                         WHEN MIN(当年未收起始日) IS NOT NULL AND MAX(当年未收截止日) IS NOT NULL
                             AND SUM(当年应收月数) > SUM(当年已收月数)
                             THEN CONCAT(DATE_FORMAT(MIN(当年未收起始日), '%Y-%m-%d'), ' ~ ', DATE_FORMAT(MAX(当年未收截止日), '%Y-%m-%d'))
                         ELSE NULL
                         END AS 未收区间,
@@ -441,24 +557,28 @@
                     SUM(当年实收金额) AS 实收金额,
                     SUM(当年折扣金额) AS 折扣金额
                 FROM calculated_data
                 WHERE 年份 BETWEEN 2016 AND 2025
                 GROUP BY 费用编号, 费用名称, 统计维度, 排序辅助
                 WHERE 统计年份 BETWEEN 2016 AND 2025
                 GROUP BY 费用编号, 费用名称, 费用类型编码, 房屋ID, 统计维度, 排序辅助
             )
-- 最终结果输出
        SELECT
        SELECT DISTINCT
            费用编号,
            费用名称,
            费用类型编码,
            房屋ID,
            统计维度,
            应收月数,
            已收月数,
            应收区间,
            已收区间,
            未收区间,
            应收金额,
            实收金额,
            折扣金额
        FROM grouped_data where 应收金额 != 0
        FROM grouped_data
        WHERE 应收金额 != 0
        ORDER BY
            费用编号,
            排序辅助;
            费用编号;
    </select>
</mapper>