chengf
2025-08-20 aab1ad64e309fa904cc9cbeba4d76b533a5b6c71
java110-db/src/main/resources/mapper/fee/ReportFeeServiceDaoImplMapper.xml
@@ -3,147 +3,106 @@
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="reportFeeServiceDaoImpl">
    <select id="repostInFee" resultType="java.util.Map">
        -- 步骤1:生成所有年份
        -- 步骤1:使用传入的yearList作为年份范围(避免递归CTE)
        WITH all_years AS (
            SELECT 2020 AS year UNION ALL
        SELECT 2021 UNION ALL
        SELECT 2022 UNION ALL
        SELECT 2023 UNION ALL
        SELECT 2024 UNION ALL
        SELECT 2025
            ),
-- 步骤2:生成所有费用类型
all_fee_types AS (
    SELECT DISTINCT
        <foreach collection="yearList" item="year" separator="UNION ALL">
            SELECT #{year} AS year
        </foreach>
        ),
        -- 步骤2:生成所有费用类型
        all_fee_types AS (
        SELECT DISTINCT
        f.fee_type_cd,
        COALESCE(dict.`name`, '未知类型') AS fee_type_name
    FROM pay_fee f
    LEFT JOIN t_dict dict ON f.fee_type_cd = dict.status_cd
),
-- 步骤3:生成"类型+年份"全量组合
all_type_year AS (
    SELECT
        FROM pay_fee f
        LEFT JOIN t_dict dict ON f.fee_type_cd = dict.status_cd
        ),
        -- 步骤3:生成"类型+年份"全量组合
        all_type_year AS (
        SELECT
        t.fee_type_cd,
        t.fee_type_name,
        y.year AS detail_year
    FROM all_fee_types t
    CROSS JOIN all_years y
),
-- 步骤4:修正原始数据聚合逻辑(关键:确保月度数据不重复计算)
original_agg AS (
    SELECT
        FROM all_fee_types t
        CROSS JOIN all_years y
        ),
        -- 步骤4:原始数据聚合(按年份列表动态处理)
        original_agg AS (
        SELECT
        f.fee_type_cd,
        COALESCE(dict.`name`, '未知类型') AS fee_type_name,
        d.detail_year,
        -- 年度总金额(基础数据,确保不重复)
        SUM(DISTINCT d.receivable_amount) AS 该年应缴总额,  -- 修正1:避免同年度金额重复计算
        -- 核心年度字段
        SUM(DISTINCT d.receivable_amount) AS 该年应缴总额,
        ROUND(SUM(DISTINCT d.receivable_amount)/12, 4) AS 每月费用,
        12 AS 应收月份数,
        -- 收缴率计算(使用DISTINCT确保分子分母匹配)
        ROUND(CASE WHEN SUM(DISTINCT d.receivable_amount) = 0 THEN 0
                  ELSE SUM(DISTINCT d.received_amount)/SUM(DISTINCT d.receivable_amount)*100
             END, 2) AS `当年收缴率(%)`,
        ELSE SUM(DISTINCT d.received_amount)/SUM(DISTINCT d.receivable_amount)*100
        END, 2) AS 当年收缴率,
        SUM(DISTINCT d.discount_amount) AS 折扣金额,
        -- 各年实缴(按付款时间统计,避免跨年度重复)
        SUM(CASE WHEN YEAR(d.pay_fee_time) = 2020 THEN d.received_amount ELSE 0 END) AS 2020年实缴,
        SUM(CASE WHEN YEAR(d.pay_fee_time) = 2021 THEN d.received_amount ELSE 0 END) AS 2021年实缴,
        SUM(CASE WHEN YEAR(d.pay_fee_time) = 2022 THEN d.received_amount ELSE 0 END) AS 2022年实缴,
        SUM(CASE WHEN YEAR(d.pay_fee_time) = 2023 THEN d.received_amount ELSE 0 END) AS 2023年实缴,
        SUM(CASE WHEN YEAR(d.pay_fee_time) = 2024 THEN d.received_amount ELSE 0 END) AS 2024年实缴,
        -- 各年实缴(遍历yearList生成字段)
        <foreach collection="yearList" item="y" separator=",">
            SUM(CASE WHEN YEAR(d.pay_fee_time) = #{y} THEN d.received_amount ELSE 0 END) AS ${y}年实缴
        </foreach>,
        -- 其他核心字段
        SUM(DISTINCT d.receivable_amount) AS 当年预算,
        SUM(CASE WHEN YEAR(d.pay_fee_time) = 2025 THEN d.received_amount ELSE 0 END) AS 2025年实缴,
        SUM(DISTINCT d.received_amount) AS 当年实缴,  -- 当年实缴=当年实际收到的金额
        SUM(DISTINCT d.discount_amount) AS 当年折扣总额,
        SUM(DISTINCT d.receivable_amount) - SUM(DISTINCT d.received_amount) AS 当年欠款,
        -- 每月应收(修正2:按月份唯一值计算,避免重复)
        SUM(DISTINCT CASE WHEN d.detail_month = 1 THEN d.receivable_amount ELSE 0 END) AS 当年1月应收,
        SUM(DISTINCT CASE WHEN d.detail_month = 2 THEN d.receivable_amount ELSE 0 END) AS 当年2月应收,
        SUM(DISTINCT CASE WHEN d.detail_month = 3 THEN d.receivable_amount ELSE 0 END) AS 当年3月应收,
        SUM(DISTINCT CASE WHEN d.detail_month = 4 THEN d.receivable_amount ELSE 0 END) AS 当年4月应收,
        SUM(DISTINCT CASE WHEN d.detail_month = 5 THEN d.receivable_amount ELSE 0 END) AS 当年5月应收,
        SUM(DISTINCT CASE WHEN d.detail_month = 6 THEN d.receivable_amount ELSE 0 END) AS 当年6月应收,
        SUM(DISTINCT CASE WHEN d.detail_month = 7 THEN d.receivable_amount ELSE 0 END) AS 当年7月应收,
        SUM(DISTINCT CASE WHEN d.detail_month = 8 THEN d.receivable_amount ELSE 0 END) AS 当年8月应收,
        SUM(DISTINCT CASE WHEN d.detail_month = 9 THEN d.receivable_amount ELSE 0 END) AS 当年9月应收,
        SUM(DISTINCT CASE WHEN d.detail_month = 10 THEN d.receivable_amount ELSE 0 END) AS 当年10月应收,
        SUM(DISTINCT CASE WHEN d.detail_month = 11 THEN d.receivable_amount ELSE 0 END) AS 当年11月应收,
        SUM(DISTINCT CASE WHEN d.detail_month = 12 THEN d.receivable_amount ELSE 0 END) AS 当年12月应收,
        -- 每月实缴(同上,避免重复)
        SUM(DISTINCT CASE WHEN d.detail_month = 1 THEN d.received_amount ELSE 0 END) AS 当年1月实缴,
        SUM(DISTINCT CASE WHEN d.detail_month = 2 THEN d.received_amount ELSE 0 END) AS 当年2月实缴,
        SUM(DISTINCT CASE WHEN d.detail_month = 3 THEN d.received_amount ELSE 0 END) AS 当年3月实缴,
        SUM(DISTINCT CASE WHEN d.detail_month = 4 THEN d.received_amount ELSE 0 END) AS 当年4月实缴,
        SUM(DISTINCT CASE WHEN d.detail_month = 5 THEN d.received_amount ELSE 0 END) AS 当年5月实缴,
        SUM(DISTINCT CASE WHEN d.detail_month = 6 THEN d.received_amount ELSE 0 END) AS 当年6月实缴,
        SUM(DISTINCT CASE WHEN d.detail_month = 7 THEN d.received_amount ELSE 0 END) AS 当年7月实缴,
        SUM(DISTINCT CASE WHEN d.detail_month = 8 THEN d.received_amount ELSE 0 END) AS 当年8月实缴,
        SUM(DISTINCT CASE WHEN d.detail_month = 9 THEN d.received_amount ELSE 0 END) AS 当年9月实缴,
        SUM(DISTINCT CASE WHEN d.detail_month = 10 THEN d.received_amount ELSE 0 END) AS 当年10月实缴,
        SUM(DISTINCT CASE WHEN d.detail_month = 11 THEN d.received_amount ELSE 0 END) AS 当年11月实缴,
        SUM(DISTINCT CASE WHEN d.detail_month = 12 THEN d.received_amount ELSE 0 END) AS 当年12月实缴
    FROM pay_fee_detail_month d
    INNER JOIN pay_fee f ON d.fee_id = f.fee_id
    LEFT JOIN t_dict dict ON f.fee_type_cd = dict.status_cd
    WHERE d.community_id = '2025081537770016' AND d.status_cd = '0'
    GROUP BY f.fee_type_cd, COALESCE(dict.`name`, '未知类型'), d.detail_year
),
-- 步骤5:全量明细行
detail_rows AS (
    SELECT
        -- 每月应收(遍历monthList生成字段)
        <foreach collection="monthList" item="m" separator=",">
            SUM(DISTINCT CASE WHEN d.detail_month = #{m} THEN d.receivable_amount ELSE 0 END) AS 当年${m}月应收
        </foreach>,
        -- 每月实缴(遍历monthList生成字段)
        <foreach collection="monthList" item="m" separator=",">
            SUM(DISTINCT CASE WHEN d.detail_month = #{m} THEN d.received_amount ELSE 0 END) AS 当年${m}月实缴
        </foreach>
        FROM pay_fee_detail_month d
        INNER JOIN pay_fee f ON d.fee_id = f.fee_id
        LEFT JOIN t_dict dict ON f.fee_type_cd = dict.status_cd
        WHERE d.community_id = #{communityId}
        AND d.status_cd = '0'
        AND d.detail_year BETWEEN #{startYear} AND #{endYear}
        GROUP BY f.fee_type_cd, COALESCE(dict.`name`, '未知类型'), d.detail_year
        ),
        -- 步骤5:全量明细行(关联聚合结果)
        detail_rows AS (
        SELECT
        a.fee_type_cd,
        a.fee_type_name,
        a.detail_year AS 费用所属年份,
        '明细' AS 行类型,
        -- 核心年度字段
        COALESCE(o.该年应缴总额, 0) AS 该年应缴总额,
        COALESCE(o.每月费用, 0) AS 每月费用,
        COALESCE(o.应收月份数, 12) AS 应收月份数,
        COALESCE(o.`当年收缴率(%)`, 0) AS `当年收缴率(%)`,
        COALESCE(o.当年收缴率, 0) AS 当年收缴率,
        COALESCE(o.折扣金额, 0) AS 折扣金额,
        -- 各年实缴
        COALESCE(o.2020年实缴, 0) AS 2020年实缴,
        COALESCE(o.2021年实缴, 0) AS 2021年实缴,
        COALESCE(o.2022年实缴, 0) AS 2022年实缴,
        COALESCE(o.2023年实缴, 0) AS 2023年实缴,
        COALESCE(o.2024年实缴, 0) AS 2024年实缴,
        -- 各年实缴(遍历yearList)
        <foreach collection="yearList" item="y" separator=",">
            COALESCE(o.${y}年实缴, 0) AS ${y}年实缴
        </foreach>,
        -- 其他核心字段
        COALESCE(o.当年预算, 0) AS 当年预算,
        COALESCE(o.2025年实缴, 0) AS 2025年实缴,
        COALESCE(o.当年实缴, 0) AS 当年实缴,
        COALESCE(o.当年折扣总额, 0) AS 当年折扣总额,
        COALESCE(o.当年欠款, 0) AS 当年欠款,
        -- 每月应收
        COALESCE(o.当年1月应收, 0) AS 当年1月应收,
        COALESCE(o.当年2月应收, 0) AS 当年2月应收,
        COALESCE(o.当年3月应收, 0) AS 当年3月应收,
        COALESCE(o.当年4月应收, 0) AS 当年4月应收,
        COALESCE(o.当年5月应收, 0) AS 当年5月应收,
        COALESCE(o.当年6月应收, 0) AS 当年6月应收,
        COALESCE(o.当年7月应收, 0) AS 当年7月应收,
        COALESCE(o.当年8月应收, 0) AS 当年8月应收,
        COALESCE(o.当年9月应收, 0) AS 当年9月应收,
        COALESCE(o.当年10月应收, 0) AS 当年10月应收,
        COALESCE(o.当年11月应收, 0) AS 当年11月应收,
        COALESCE(o.当年12月应收, 0) AS 当年12月应收,
        -- 每月实缴
        COALESCE(o.当年1月实缴, 0) AS 当年1月实缴,
        COALESCE(o.当年2月实缴, 0) AS 当年2月实缴,
        COALESCE(o.当年3月实缴, 0) AS 当年3月实缴,
        COALESCE(o.当年4月实缴, 0) AS 当年4月实缴,
        COALESCE(o.当年5月实缴, 0) AS 当年5月实缴,
        COALESCE(o.当年6月实缴, 0) AS 当年6月实缴,
        COALESCE(o.当年7月实缴, 0) AS 当年7月实缴,
        COALESCE(o.当年8月实缴, 0) AS 当年8月实缴,
        COALESCE(o.当年9月实缴, 0) AS 当年9月实缴,
        COALESCE(o.当年10月实缴, 0) AS 当年10月实缴,
        COALESCE(o.当年11月实缴, 0) AS 当年11月实缴,
        COALESCE(o.当年12月实缴, 0) AS 当年12月实缴
    FROM all_type_year a
    LEFT JOIN original_agg o
        -- 每月应收(遍历monthList)
        <foreach collection="monthList" item="m" separator=",">
            COALESCE(o.当年${m}月应收, 0) AS 当年${m}月应收
        </foreach>,
        -- 每月实缴(遍历monthList)
        <foreach collection="monthList" item="m" separator=",">
            COALESCE(o.当年${m}月实缴, 0) AS 当年${m}月实缴
        </foreach>
        FROM all_type_year a
        LEFT JOIN original_agg o
        ON a.fee_type_cd = o.fee_type_cd
        AND a.detail_year = o.detail_year
),
-- 步骤6:类型总计行
type_total_rows AS (
    SELECT
        ),
        -- 步骤6:类型总计行(聚合明细行)
        type_total_rows AS (
        SELECT
        fee_type_cd,
        fee_type_name,
        '类型总计' AS 费用所属年份,
@@ -152,52 +111,32 @@
        ROUND(SUM(该年应缴总额) / (12 * COUNT(DISTINCT 费用所属年份)), 4) AS 每月费用,
        12 * COUNT(DISTINCT 费用所属年份) AS 应收月份数,
        ROUND(CASE WHEN SUM(该年应缴总额) = 0 THEN 0
                  ELSE SUM(2020年实缴 + 2021年实缴 + 2022年实缴 + 2023年实缴 + 2024年实缴 + 2025年实缴)
                       / SUM(该年应缴总额) * 100
             END, 2) AS `当年收缴率(%)`,
        ELSE SUM(当年实缴) / SUM(该年应缴总额) * 100
        END, 2) AS 当年收缴率,
        SUM(折扣金额) AS 折扣金额,
        -- 各年实缴合计
        SUM(2020年实缴) AS 2020年实缴,
        SUM(2021年实缴) AS 2021年实缴,
        SUM(2022年实缴) AS 2022年实缴,
        SUM(2023年实缴) AS 2023年实缴,
        SUM(2024年实缴) AS 2024年实缴,
        -- 各年实缴合计(遍历yearList)
        <foreach collection="yearList" item="y" separator=",">
            SUM(${y}年实缴) AS ${y}年实缴
        </foreach>,
        -- 其他核心字段合计
        SUM(当年预算) AS 当年预算,
        SUM(2025年实缴) AS 2025年实缴,
        SUM(当年实缴) AS 当年实缴,
        SUM(当年折扣总额) AS 当年折扣总额,
        SUM(当年欠款) AS 当年欠款,
        -- 每月应收合计
        SUM(当年1月应收) AS 当年1月应收,
        SUM(当年2月应收) AS 当年2月应收,
        SUM(当年3月应收) AS 当年3月应收,
        SUM(当年4月应收) AS 当年4月应收,
        SUM(当年5月应收) AS 当年5月应收,
        SUM(当年6月应收) AS 当年6月应收,
        SUM(当年7月应收) AS 当年7月应收,
        SUM(当年8月应收) AS 当年8月应收,
        SUM(当年9月应收) AS 当年9月应收,
        SUM(当年10月应收) AS 当年10月应收,
        SUM(当年11月应收) AS 当年11月应收,
        SUM(当年12月应收) AS 当年12月应收,
        -- 每月实缴合计
        SUM(当年1月实缴) AS 当年1月实缴,
        SUM(当年2月实缴) AS 当年2月实缴,
        SUM(当年3月实缴) AS 当年3月实缴,
        SUM(当年4月实缴) AS 当年4月实缴,
        SUM(当年5月实缴) AS 当年5月实缴,
        SUM(当年6月实缴) AS 当年6月实缴,
        SUM(当年7月实缴) AS 当年7月实缴,
        SUM(当年8月实缴) AS 当年8月实缴,
        SUM(当年9月实缴) AS 当年9月实缴,
        SUM(当年10月实缴) AS 当年10月实缴,
        SUM(当年11月实缴) AS 当年11月实缴,
        SUM(当年12月实缴) AS 当年12月实缴
    FROM detail_rows
    GROUP BY fee_type_cd, fee_type_name
),
-- 步骤7:总合计行
grand_total_row AS (
    SELECT
        -- 每月应收合计(遍历monthList)
        <foreach collection="monthList" item="m" separator=",">
            SUM(当年${m}月应收) AS 当年${m}月应收
        </foreach>,
        -- 每月实缴合计(遍历monthList)
        <foreach collection="monthList" item="m" separator=",">
            SUM(当年${m}月实缴) AS 当年${m}月实缴
        </foreach>
        FROM detail_rows
        GROUP BY fee_type_cd, fee_type_name
        ),
        -- 步骤7:总合计行(聚合所有数据)
        grand_total_row AS (
        SELECT
        'ALL' AS fee_type_cd,
        '所有类型总计' AS fee_type_name,
        '总合计' AS 费用所属年份,
@@ -206,65 +145,109 @@
        ROUND(SUM(该年应缴总额) / (12 * COUNT(DISTINCT 费用所属年份)), 4) AS 每月费用,
        12 * COUNT(DISTINCT 费用所属年份) AS 应收月份数,
        ROUND(CASE WHEN SUM(该年应缴总额) = 0 THEN 0
                  ELSE SUM(2020年实缴 + 2021年实缴 + 2022年实缴 + 2023年实缴 + 2024年实缴 + 2025年实缴)
                       / SUM(该年应缴总额) * 100
             END, 2) AS `当年收缴率`,
        ELSE SUM(当年实缴) / SUM(该年应缴总额) * 100
        END, 2) AS 当年收缴率,
        SUM(折扣金额) AS 折扣金额,
        -- 各年实缴总合计
        SUM(2020年实缴) AS 2020年实缴,
        SUM(2021年实缴) AS 2021年实缴,
        SUM(2022年实缴) AS 2022年实缴,
        SUM(2023年实缴) AS 2023年实缴,
        SUM(2024年实缴) AS 2024年实缴,
        -- 各年实缴总合计(遍历yearList)
        <foreach collection="yearList" item="y" separator=",">
            SUM(${y}年实缴) AS ${y}年实缴
        </foreach>,
        -- 其他核心字段总合计
        SUM(当年预算) AS 当年预算,
        SUM(2025年实缴) AS 2025年实缴,
        SUM(当年实缴) AS 当年实缴,
        SUM(当年折扣总额) AS 当年折扣总额,
        SUM(当年欠款) AS 当年欠款,
        -- 每月应收总合计
        SUM(当年1月应收) AS 当年1月应收,
        SUM(当年2月应收) AS 当年2月应收,
        SUM(当年3月应收) AS 当年3月应收,
        SUM(当年4月应收) AS 当年4月应收,
        SUM(当年5月应收) AS 当年5月应收,
        SUM(当年6月应收) AS 当年6月应收,
        SUM(当年7月应收) AS 当年7月应收,
        SUM(当年8月应收) AS 当年8月应收,
        SUM(当年9月应收) AS 当年9月应收,
        SUM(当年10月应收) AS 当年10月应收,
        SUM(当年11月应收) AS 当年11月应收,
        SUM(当年12月应收) AS 当年12月应收,
        -- 每月实缴总合计
        SUM(当年1月实缴) AS 当年1月实缴,
        SUM(当年2月实缴) AS 当年2月实缴,
        SUM(当年3月实缴) AS 当年3月实缴,
        SUM(当年4月实缴) AS 当年4月实缴,
        SUM(当年5月实缴) AS 当年5月实缴,
        SUM(当年6月实缴) AS 当年6月实缴,
        SUM(当年7月实缴) AS 当年7月实缴,
        SUM(当年8月实缴) AS 当年8月实缴,
        SUM(当年9月实缴) AS 当年9月实缴,
        SUM(当年10月实缴) AS 当年10月实缴,
        SUM(当年11月实缴) AS 当年11月实缴,
        SUM(当年12月实缴) AS 当年12月实缴
    FROM detail_rows
)
        -- 每月应收总合计(遍历monthList)
        <foreach collection="monthList" item="m" separator=",">
            SUM(当年${m}月应收) AS 当年${m}月应收
        </foreach>,
        -- 每月实缴总合计(遍历monthList)
        <foreach collection="monthList" item="m" separator=",">
            SUM(当年${m}月实缴) AS 当年${m}月实缴
        </foreach>
        FROM detail_rows
        )
-- 最终结果
        -- 最终结果:合并所有行并排序
        SELECT * FROM (
                          SELECT * FROM type_total_rows
                          UNION ALL
                          SELECT * FROM detail_rows
                          UNION ALL
                          SELECT * FROM grand_total_row
                      ) AS all_rows
        SELECT * FROM type_total_rows
        UNION ALL
        SELECT * FROM detail_rows
        UNION ALL
        SELECT * FROM grand_total_row
        ) AS all_rows
        ORDER BY
            CASE
                WHEN 行类型 = '总合计' THEN 2
                WHEN 行类型 = '类型总计' THEN 0
                ELSE 1
                END,
            fee_type_cd,
            CASE WHEN 费用所属年份 = '类型总计' THEN 0 ELSE CAST(费用所属年份 AS UNSIGNED) END;
        CASE
        WHEN 行类型 = '总合计' THEN 2
        WHEN 行类型 = '类型总计' THEN 0
        ELSE 1
        END,
        fee_type_cd,
        CASE WHEN 费用所属年份 = '类型总计' THEN 0 ELSE CAST(费用所属年份 AS UNSIGNED) END
    </select>
</mapper>
    <insert id="saveReport" parameterType="Map">
        INSERT INTO report_query_record (
            id,
            refresh_time,
            end_year,
            community_id,
            community_name,
            report_content,
            operator,
            operator_id,
            query_status,
            create_time,
            update_time
        ) VALUES (
                     #{id},
                     now(),
                     #{endYear},
                     #{communityId},
                     null,
                     #{reportContent},
                     #{operator},
                     null,
                     #{queryStatus},
                     now(),
                     now()
                 )
    </insert>
    <select id="queryReport" resultType="java.util.Map">
        SELECT
        id,
        refresh_time AS refreshTime,
        end_year AS endYear,
        community_id AS communityId,
        community_name AS communityName,
        report_content AS reportContent,
        operator,
        operator_id AS operatorId,
        query_status AS queryStatus,
        create_time AS createTime,
        update_time AS updateTime
        FROM report_query_record
        WHERE 1 = 1
        <if test="communityId != null and communityId != ''">
            AND community_id = #{communityId}
        </if>
        <if test="endYear != null and endYear != ''">
            AND end_year = #{endYear}
        </if>
        <if test="queryStatus != null and queryStatus != ''">
            AND query_status = #{queryStatus}
        </if>
        <if test="operatorId != null and operatorId != ''">
            AND operator_id = #{operatorId}
        </if>
        <if test="startTime != null and startTime != ''">
            AND create_time >= #{startTime}
        </if>
        <if test="endTime != null and endTime != ''">
            AND create_time &lt;= #{endTime}
        </if>
        ORDER BY create_time DESC
        <if test="pageNum != null and pageSize != null">
            LIMIT #{pageNum}, #{pageSize}
        </if>
    </select>
</mapper>