<?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="reportFeeServiceDaoImpl">
|
<select id="repostInFee" resultType="java.util.Map">
|
-- 步骤1:使用传入的yearList作为年份范围(避免递归CTE)
|
WITH all_years AS (
|
<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
|
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
|
f.fee_type_cd,
|
COALESCE(dict.`name`, '未知类型') AS fee_type_name,
|
d.detail_year,
|
-- 核心年度字段
|
SUM(DISTINCT d.receivable_amount) AS 该年应缴总额,
|
ROUND(SUM(DISTINCT d.receivable_amount)/12, 4) AS 每月费用,
|
12 AS 应收月份数,
|
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 当年收缴率,
|
SUM(DISTINCT d.discount_amount) AS 折扣金额,
|
-- 各年实缴(遍历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(DISTINCT d.received_amount) AS 当年实缴, -- 当年实缴=当年实际收到的金额
|
SUM(DISTINCT d.discount_amount) AS 当年折扣总额,
|
SUM(DISTINCT d.receivable_amount) - SUM(DISTINCT d.received_amount) AS 当年欠款,
|
-- 每月应收(遍历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 折扣金额,
|
-- 各年实缴(遍历yearList)
|
<foreach collection="yearList" item="y" separator=",">
|
COALESCE(o.${y}年实缴, 0) AS ${y}年实缴
|
</foreach>,
|
-- 其他核心字段
|
COALESCE(o.当年预算, 0) AS 当年预算,
|
COALESCE(o.当年实缴, 0) AS 当年实缴,
|
COALESCE(o.当年折扣总额, 0) AS 当年折扣总额,
|
COALESCE(o.当年欠款, 0) AS 当年欠款,
|
-- 每月应收(遍历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
|
fee_type_cd,
|
fee_type_name,
|
'类型总计' AS 费用所属年份,
|
'类型总计' AS 行类型,
|
SUM(该年应缴总额) AS 该年应缴总额,
|
ROUND(SUM(该年应缴总额) / (12 * COUNT(DISTINCT 费用所属年份)), 4) AS 每月费用,
|
12 * COUNT(DISTINCT 费用所属年份) AS 应收月份数,
|
ROUND(CASE WHEN SUM(该年应缴总额) = 0 THEN 0
|
ELSE SUM(当年实缴) / SUM(该年应缴总额) * 100
|
END, 2) AS 当年收缴率,
|
SUM(折扣金额) AS 折扣金额,
|
-- 各年实缴合计(遍历yearList)
|
<foreach collection="yearList" item="y" separator=",">
|
SUM(${y}年实缴) AS ${y}年实缴
|
</foreach>,
|
-- 其他核心字段合计
|
SUM(当年预算) AS 当年预算,
|
SUM(当年实缴) AS 当年实缴,
|
SUM(当年折扣总额) AS 当年折扣总额,
|
SUM(当年欠款) AS 当年欠款,
|
-- 每月应收合计(遍历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 费用所属年份,
|
'总合计' AS 行类型,
|
SUM(该年应缴总额) AS 该年应缴总额,
|
ROUND(SUM(该年应缴总额) / (12 * COUNT(DISTINCT 费用所属年份)), 4) AS 每月费用,
|
12 * COUNT(DISTINCT 费用所属年份) AS 应收月份数,
|
ROUND(CASE WHEN SUM(该年应缴总额) = 0 THEN 0
|
ELSE SUM(当年实缴) / SUM(该年应缴总额) * 100
|
END, 2) AS 当年收缴率,
|
SUM(折扣金额) AS 折扣金额,
|
-- 各年实缴总合计(遍历yearList)
|
<foreach collection="yearList" item="y" separator=",">
|
SUM(${y}年实缴) AS ${y}年实缴
|
</foreach>,
|
-- 其他核心字段总合计
|
SUM(当年预算) AS 当年预算,
|
SUM(当年实缴) AS 当年实缴,
|
SUM(当年折扣总额) AS 当年折扣总额,
|
SUM(当年欠款) AS 当年欠款,
|
-- 每月应收总合计(遍历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
|
ORDER BY
|
CASE
|
WHEN 行类型 = '总合计' THEN 2
|
WHEN 行类型 = '类型总计' THEN 0
|
ELSE 1
|
END,
|
fee_type_cd,
|
CASE WHEN 费用所属年份 = '类型总计' THEN 0 ELSE CAST(费用所属年份 AS UNSIGNED) END
|
</select>
|
<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 <= #{endTime}
|
</if>
|
ORDER BY create_time DESC
|
<if test="pageNum != null and pageSize != null">
|
LIMIT #{pageNum}, #{pageSize}
|
</if>
|
</select>
|
</mapper>
|