chengf
2025-08-26 ace8009da36d622f72e4145eb0b38f0a344f3a45
暂存0825、
22个文件已修改
526 ■■■■ 已修改文件
java110-bean/src/main/java/com/java110/dto/org/OrgTreeDto.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
java110-db/src/main/resources/mapper/community/RoomServiceDaoImplMapper.xml 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
java110-db/src/main/resources/mapper/fee/FeeServiceDaoImplMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
java110-db/src/main/resources/mapper/fee/ReportFeeServiceDaoImplMapper.xml 322 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
java110-db/src/main/resources/mapper/store/ContractServiceDaoImplMapper.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
java110-db/src/main/resources/mapper/user/UserServiceDaoImplMapper.xml 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
java110-interface/src/main/java/com/java110/intf/fee/IFeeInnerServiceSMO.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
java110-interface/src/main/java/com/java110/intf/fee/IReportFeeInnerServiceSMO.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/cmd/fee/ReportFeePropertyCmd.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/cmd/feeConfig/UpdateFeeConfigCmd.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/dao/IFeeServiceDao.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/dao/IReportFeeServiceDao.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/dao/impl/FeeServiceDaoImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/dao/impl/IReportFeeServiceDaoImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/discount/impl/ReductionFeeRule.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/smo/impl/FeeInnerServiceSMOImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-fee/src/main/java/com/java110/fee/smo/impl/ReportFeeInnerServiceSMOImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-job/src/main/java/com/java110/job/importData/adapt/ImportCarHistoryFeeDetailQueueDataAdapt.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-job/src/main/java/com/java110/job/importData/adapt/ImportHistoryFeeDetailQueueDataAdapt.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-store/src/main/java/com/java110/store/api/ContractPartyaApi.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-user/src/main/java/com/java110/user/cmd/org/ListOrgTreeCmd.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service-user/src/main/java/com/java110/user/cmd/user/UserStaffModifyCmd.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
java110-bean/src/main/java/com/java110/dto/org/OrgTreeDto.java
@@ -22,11 +22,12 @@
    }
    public OrgTreeDto(String id, String text,String parentId,String allOrgName) {
    public OrgTreeDto(String id, String text,String parentId,String allOrgName,String orgLevel) {
        this.id = id;
        this.text = text;
        this.parentId = parentId;
        this.allOrgName = allOrgName;
        this.orgLevel = orgLevel;
    }
    private String id;
@@ -34,8 +35,16 @@
    private String text;
    private String parentId;
    private String allOrgName;
    private String orgLevel;
    private List<OrgTreeDto> children;
    public String getOrgLevel() {
        return orgLevel;
    }
    public void setOrgLevel(String orgLevel) {
        this.orgLevel = orgLevel;
    }
    public String getId() {
        return id;
java110-db/src/main/resources/mapper/community/RoomServiceDaoImplMapper.xml
@@ -983,6 +983,13 @@
         inner join f_floor bf on bu.floor_id = bf.floor_id
         left join building_owner_room_rel borr on borr.room_id = br.room_id
         left join building_owner bo on bo.owner_id = borr.owner_id
        limit 1,10
        where 1 = 1
            <if test="communityId != null">
                and br.community_id = #{communityId}
            </if>
        <if test="page != -1 and page != null">
            limit #{page},#{row}
        </if>
    </select>
</mapper>
java110-db/src/main/resources/mapper/fee/FeeServiceDaoImplMapper.xml
@@ -954,4 +954,8 @@
          and t.batch_id = #{batchId}
          and t.community_id = #{communityId}
    </update>
    <select id="countValidPayFeeByConfigId" parameterType="Map" resultType="Integer">
        select count(1) from pay_fee where config_id = #{configId} and status_cd = 0
    </select>
</mapper>
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>
java110-db/src/main/resources/mapper/store/ContractServiceDaoImplMapper.xml
@@ -43,6 +43,15 @@
        <if test="aLink !=null and aLink != ''">
            and t.a_link= #{aLink}
        </if>
        <if test="aPartyaId !=null and aPartyaId != ''">
            and t.a_partya_id= #{aPartyaId}
        </if>
        <if test="bPartyaId !=null and bPartyaId != ''">
            and t.b_partya_id= #{bPartyaId}
        </if>
        <if test="cPartyaId !=null and cPartyaId != ''">
            and t.c_partya_id= #{cPartyaId}
        </if>
        <if test="aContacts !=null and aContacts != ''">
            and t.a_contacts= #{aContacts}
        </if>
java110-db/src/main/resources/mapper/user/UserServiceDaoImplMapper.xml
@@ -607,6 +607,9 @@
        userName,u.email,u.address,u.password,u.location_cd,u.location_cd locationCd,
        u.age,u.sex,u.tel,u.level_cd,u.b_id,u.level_cd levelCd,u.score
        from u_user u
        <if test="storeId != null and storeId !=''">
            left join s_store_user t1 on u.user_id = t1.user_id
        </if>
        <if test="openId != null and openId !=''">
            ,u_user_attr ua
        </if>
@@ -617,7 +620,9 @@
            ,u_user_attr ua
        </if>
        where 1= 1
        <if test="storeId != null and storeId !=''">
            and t1.store_id = #{storeId}
        </if>
        <if test="openId != null and openId != ''">
            and u.user_id = ua.user_id
            and ua.spec_cd in ('100201911001','100201911003')
java110-interface/src/main/java/com/java110/intf/fee/IFeeInnerServiceSMO.java
@@ -210,4 +210,10 @@
    int deleteFeesByBatch(@RequestBody PayFeePo payFeePo);
    int getFeeInfoBus(FeeDto feeDto);
    /**
     * 根据费用配置id查询有效的费用关联
     */
    @RequestMapping(value = "/countValidPayFeeByConfigId", method = RequestMethod.POST)
    int countValidPayFeeByConfigId(@RequestBody String configId);
}
java110-interface/src/main/java/com/java110/intf/fee/IReportFeeInnerServiceSMO.java
@@ -21,4 +21,6 @@
    List<ReportQueryRecord> queryReport(Map map);
    List<Map> repostPaidInFeeByWhiteOrder(FeeQueryParams feeQueryParams);
    List<Map> onceRoomFee(Map map);
}
service-fee/src/main/java/com/java110/fee/cmd/fee/ReportFeePropertyCmd.java
@@ -7,12 +7,14 @@
import com.java110.core.event.cmd.CmdEvent;
import com.java110.dto.community.CommunityDto;
import com.java110.dto.dict.DictDto;
import com.java110.dto.fee.FeeConfigDto;
import com.java110.dto.fee.FeeDto;
import com.java110.dto.report.ReportQueryRecord;
import com.java110.dto.room.RoomDto;
import com.java110.intf.community.ICommunityInnerServiceSMO;
import com.java110.intf.community.IRoomInnerServiceSMO;
import com.java110.intf.dev.IDictV1InnerServiceSMO;
import com.java110.intf.fee.IFeeConfigInnerServiceSMO;
import com.java110.intf.fee.IReportFeeInnerServiceSMO;
import com.java110.utils.exception.CmdException;
import com.java110.utils.util.Assert;
@@ -43,6 +45,9 @@
    @Autowired
    private IRoomInnerServiceSMO roomInnerServiceSMOImpl;
    @Autowired
    private IFeeConfigInnerServiceSMO  feeConfigInnerServiceSMOImpl;
    @Override
    public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException {
@@ -83,10 +88,25 @@
        }
        else{
            int row = Integer.parseInt(reqJson.containsKey("row")?reqJson.getString("row"):"10");
            int page = Integer.parseInt(reqJson.containsKey("page")?reqJson.getString("page"):"1");
            startYear = 2016;
            endYear = 2025;
            Object[][] test = new Object[row][];
            RoomDto roomDto = new RoomDto();
            roomDto.setRoomId(reqJson.getString("communityId"));
            roomDto.setCommunityId(reqJson.getString("communityId"));
            roomDto.setRow(row);
            roomDto.setPage(page);
            List<Map> rooms = roomInnerServiceSMOImpl.queryRoomsAsReport(roomDto);
            FeeConfigDto feeConfigDto = new FeeConfigDto();
            feeConfigDto.setCommunityId(reqJson.getString("communityId"));
            feeConfigDto.setConfigIds(new String[]{"630000001","630000002"});
            List<FeeConfigDto> feeConfigDtos = feeConfigInnerServiceSMOImpl.queryFeeConfigs(feeConfigDto);
            int arrLength = 11 + (2 * feeConfigDtos.size()) + 8 + ((endYear - startYear + 1) * 3);
            String[] header = new String[arrLength];
            headerDoing(header,feeConfigDtos,startYear,endYear);
            for(Map room : rooms){
            }
            reportQueryRecord.setCommunityId(reqJson.getString("communityId"));
@@ -105,4 +125,36 @@
            context.setResponseEntity(responseEntity);
        }
    }
    private void headerDoing(String[] header,List<FeeConfigDto> feeConfigDtos,int startYear, int endYear) {
        int feeRow = feeConfigDtos.size();
        header[0] = "序号";
        header[1] = "物业类型";
        header[2] = "楼栋号/弄";
        header[3] = "门号";
        header[4] = "室号";
        header[5] = "门室号";
        header[6] = "产证地址";
        header[7] = "收费面积(m²)";
        header[8] = "购房人姓名";
        header[9] = "门室号";
        for (int i=0;i<feeRow;i++){
            header[9 + i + 1] = feeConfigDtos.get(0).getFeeName();
        }
        header[9 + feeRow + 1] = "年应收款";
        header[9 + feeRow + 2] = "合计(2020年1月-至今)-应收";
        header[9 + feeRow + 3] = "合计(2020年1月-至今)-实收";
        header[9 + feeRow + 4] = "合计(2020年1月-至今)-代收";
        header[9 + feeRow + 5] = "合计(2020年1月-至今)-2026年";
        header[9 + feeRow + 6] = "合计(2020年1月-至今)-2027年";
        header[9 + feeRow + 7] = "合计(2020年1月-至今)-待收月数";
        header[9 + feeRow + 8] = "合计(2020年1月-至今)-待收金额";
        header[9 + feeRow + 9] = "代收区间";
        for (int i = startYear ; i <= endYear ; i++){
            header[9 + feeRow + 9 + ((i - startYear) * 3) + 1] = "历年实收"+i+"-已收月数";
            header[9 + feeRow + 9 + ((i - startYear) * 3) + 2] = "历年实收"+i+"-已收区间";
            header[9 + feeRow + 9 + ((i - startYear) * 3) + 3] = "历年实收"+i+"-未收区间";
        }
        header[9 + feeRow + 9 + ((endYear - startYear) * 3) + 4] = "打折金额汇总";
    }
}
service-fee/src/main/java/com/java110/fee/cmd/feeConfig/UpdateFeeConfigCmd.java
@@ -9,10 +9,7 @@
import com.java110.dto.fee.FeeConfigDto;
import com.java110.dto.fee.FeeDto;
import com.java110.dto.payFee.PayFeeRuleDto;
import com.java110.intf.fee.IFeeConfigInnerServiceSMO;
import com.java110.intf.fee.IPayFeeConfigV1InnerServiceSMO;
import com.java110.intf.fee.IPayFeeRuleV1InnerServiceSMO;
import com.java110.intf.fee.IPayFeeV1InnerServiceSMO;
import com.java110.intf.fee.*;
import com.java110.po.fee.PayFeeConfigPo;
import com.java110.po.fee.PayFeePo;
import com.java110.utils.exception.CmdException;
@@ -31,6 +28,9 @@
    @Autowired
    private IFeeConfigInnerServiceSMO feeConfigInnerServiceSMOImpl;
    @Autowired
    private IFeeInnerServiceSMO feeInnerServiceSMO;
    @Autowired
    private IPayFeeRuleV1InnerServiceSMO payFeeRuleV1InnerServiceSMOImpl;
@@ -61,6 +61,10 @@
        feeConfigDto.setConfigId(reqJson.getString("configId"));
        List<FeeConfigDto> feeConfigDtos = feeConfigInnerServiceSMOImpl.queryFeeConfigs(feeConfigDto);
        Assert.listOnlyOne(feeConfigDtos, "未找到该费用项");
        int validCount = feeInnerServiceSMO.countValidPayFeeByConfigId(reqJson.getString("configId"));
        if (validCount > 0) {
            throw new CmdException("关联生效中费用,无法修改,请撤销关联费用后重试!");
        }
        JSONObject businessFeeConfig = new JSONObject();
        businessFeeConfig.putAll(reqJson);
        businessFeeConfig.put("isDefault", feeConfigDtos.get(0).getIsDefault());
service-fee/src/main/java/com/java110/fee/dao/IFeeServiceDao.java
@@ -175,4 +175,6 @@
    int deleteFeesByBatch(Map beanCovertMap);
    int getFeeInfoBus(Map map);
    int countValidPayFeeByConfigId(Map info);
}
service-fee/src/main/java/com/java110/fee/dao/IReportFeeServiceDao.java
@@ -17,4 +17,6 @@
    List<ReportQueryRecord> queryReport(Map map);
    List<Map> repostPaidInFeeByWhiteOrder(Map map);
    List<Map> onceRoomFee(Map map);
}
service-fee/src/main/java/com/java110/fee/dao/impl/FeeServiceDaoImpl.java
@@ -287,6 +287,14 @@
        return saveFlag;
    }
    /**
     * 根据费用配置id查询有效的费用关联
     */
    @Override
    public int countValidPayFeeByConfigId(Map info) {
        return sqlSessionTemplate.insert("feeServiceDaoImpl.countValidPayFeeByConfigId", info);
    }
    @Override
    public int computeBillOweFeeCount(Map beanCovertMap) {
        List<Map> infos = sqlSessionTemplate.selectList("feeServiceDaoImpl.computeBillOweFeeCount", beanCovertMap);
service-fee/src/main/java/com/java110/fee/dao/impl/IReportFeeServiceDaoImpl.java
@@ -73,4 +73,9 @@
    public List<Map> repostPaidInFeeByWhiteOrder(Map map) {
        return sqlSessionTemplate.selectList("reportFeeServiceDaoImpl.repostPaidInFeeByWhiteOrder", map);
    }
    @Override
    public List<Map> onceRoomFee(Map map) {
        return sqlSessionTemplate.selectList("reportFeeServiceDaoImpl.onceRoomFee", map);
    }
}
service-fee/src/main/java/com/java110/fee/discount/impl/ReductionFeeRule.java
@@ -67,7 +67,7 @@
            }
        }
        if (feeDiscountDto.getCycles() < month) {
        if (feeDiscountDto.getCycles() < month) {//缴费周期数(feeDiscountDto.getCycles())    month(获取到的折扣配置的月份)
            ComputeDiscountDto computeDiscountDto = new ComputeDiscountDto();
            computeDiscountDto.setDiscountId(feeDiscountDto.getDiscountId());
            computeDiscountDto.setDiscountType(FeeDiscountDto.DISCOUNT_TYPE_D);
@@ -79,9 +79,12 @@
            return computeDiscountDto;
        }
        Double cycle = feeDiscountDto.getCycles() / month;
        Double cycle = 1.0; //折扣周期  = 缴费周期数 / 折扣配置的月份
        if (feeDiscountDto.getCycles() < month) {
            cycle = feeDiscountDto.getCycles();
        }
        BigDecimal cycleDec = new BigDecimal(cycle.intValue());
        //计算
        double discountPrice = cycleDec.multiply(new BigDecimal(money)).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
        ComputeDiscountDto computeDiscountDto = new ComputeDiscountDto();
service-fee/src/main/java/com/java110/fee/smo/impl/FeeInnerServiceSMOImpl.java
@@ -425,4 +425,11 @@
    public void setUserInnerServiceSMOImpl(IUserInnerServiceSMO userInnerServiceSMOImpl) {
        this.userInnerServiceSMOImpl = userInnerServiceSMOImpl;
    }
    @Override
    public int countValidPayFeeByConfigId(String configId) {
        Map info = new HashMap();
        info.put("configId", configId);
        return feeServiceDaoImpl.countValidPayFeeByConfigId(info);
    }
}
service-fee/src/main/java/com/java110/fee/smo/impl/ReportFeeInnerServiceSMOImpl.java
@@ -43,4 +43,8 @@
    public List<Map> repostPaidInFeeByWhiteOrder(FeeQueryParams feeQueryParams) {
        return iReportFeeServiceDao.repostPaidInFeeByWhiteOrder(BeanConvertUtil.beanCovertMap(feeQueryParams));
    }
    @Override
    public List<Map> onceRoomFee(Map map){
        return iReportFeeServiceDao.onceRoomFee(map);
    }
}
service-job/src/main/java/com/java110/job/importData/adapt/ImportCarHistoryFeeDetailQueueDataAdapt.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.java110.core.factory.GenerateCodeFactory;
import com.java110.dto.contract.ContractPartyaDto;
import com.java110.dto.fee.FeeAttrDto;
import com.java110.dto.fee.FeeConfigDto;
import com.java110.dto.fee.FeeDetailDto;
@@ -14,6 +15,7 @@
import com.java110.fee.api.FeeDiscountApi;
import com.java110.intf.community.IRoomInnerServiceSMO;
import com.java110.intf.fee.*;
import com.java110.intf.store.IContractPartyaInnerServiceSMO;
import com.java110.intf.user.IOwnerCarInnerServiceSMO;
import com.java110.intf.user.IOwnerRoomRelV1InnerServiceSMO;
import com.java110.job.importData.DefaultImportData;
@@ -75,6 +77,8 @@
    @Autowired
    private IOwnerRoomRelV1InnerServiceSMO ownerRoomRelV1InnerServiceSMOImpl;
    @Autowired
    private IContractPartyaInnerServiceSMO contractPartyaInnerServiceSMOImpl;
    @Override
    public void importData(List<AssetImportLogDetailDto> assetImportLogDetailDtos) {
@@ -137,19 +141,27 @@
        }
        List<RoomDto> roomDtos = iRoomInnerServiceSMOImpl.queryRooms(roomDto);
        try {
            importRoomFee.setRoomId(roomDtos.get(0).getRoomId());
        }catch (Exception e){
            if(!(importRoomFee.getPayObjId().equals("7777"))){
                updateImportLogDetailState(importRoomFee.getDetailId(),new IllegalArgumentException("费用项"+importRoomFee.getFeeName()+"不存在"));
                throw new IllegalArgumentException("门室号"+importRoomFee.getDoorRoomNum()+"未查询到房屋");
            if (importRoomFee.getPayObjId().equals("7777")){
                ContractPartyaDto contractPartyaDto = new ContractPartyaDto();
                contractPartyaDto.setPartyA(importRoomFee.getDoorRoomNum());
                List<ContractPartyaDto> contractPartyaDtos = contractPartyaInnerServiceSMOImpl.queryContractPartyas(contractPartyaDto);
                if (contractPartyaDtos != null && contractPartyaDtos.size() > 0) {
                    importRoomFee.setRoomId(contractPartyaDtos.get(0).getPartyaId());
                }else{
                    throw new RuntimeException();
                }
            }else{
                importRoomFee.setRoomId(roomDtos.get(0).getRoomId());
            }
        }catch (Exception e){
            updateImportLogDetailState(importRoomFee.getDetailId(),new IllegalArgumentException("费用项"+importRoomFee.getFeeName()+"不存在"));
            throw new IllegalArgumentException("门室号/合同主体:"+importRoomFee.getDoorRoomNum()+"未查询到");
        }
        PayFeeDetailPo payFeeDetailPo = new PayFeeDetailPo();
        payFeeDetailPo.setPayOrderId(importRoomFee.getRoomId());
        payFeeDetailPo.setCycles(importRoomFee.getCycle());
        payFeeDetailPo.setCreateTime(importRoomFee.getCreateTime());
        payFeeDetailPo.setCommunityId(importRoomFee.getCommunityId());
        payFeeDetailPo.setPayOrderId(importRoomFee.getRoomId());
        int count = feeDetailInnerServiceSMOImpl.queryFeeDetailsCountByVo(payFeeDetailPo);
        if (count > 0) {
service-job/src/main/java/com/java110/job/importData/adapt/ImportHistoryFeeDetailQueueDataAdapt.java
@@ -230,7 +230,6 @@
        if(!(ListUtil.isNull(importCarFees))){
            importCarHistoryFeeDetailQueueDataAdapt.importCarFeeDetails(importCarFees.get(0).getStoreId(), importCarFees.get(0).getUserId(), importCarFees, importCarFees.get(0).getBatchId());
        }
    }
    private void importFeeDetailsByCarInout(List<CarInoutPo> carInoutPos) {
service-store/src/main/java/com/java110/store/api/ContractPartyaApi.java
@@ -1,7 +1,9 @@
package com.java110.store.api;
import com.alibaba.fastjson.JSONObject;
import com.java110.dto.contract.ContractDto;
import com.java110.dto.contract.ContractPartyaDto;
import com.java110.intf.store.IContractInnerServiceSMO;
import com.java110.po.contract.ContractPartyaPo;
import com.java110.store.bmo.contractPartya.IDeleteContractPartyaBMO;
import com.java110.store.bmo.contractPartya.IGetContractPartyaBMO;
@@ -11,7 +13,10 @@
import com.java110.utils.util.BeanConvertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping(value = "/contractPartya")
@@ -26,6 +31,8 @@
    @Autowired
    private IGetContractPartyaBMO getContractPartyaBMOImpl;
    @Autowired
    private IContractInnerServiceSMO contractInnerServiceSMOImpl;
    /**
     * 微信保存消息模板
@@ -93,6 +100,19 @@
        ContractPartyaPo contractPartyaPo = BeanConvertUtil.covertBean(reqJson, ContractPartyaPo.class);
        //判断该活动主体是否被使用
        ContractDto contractDto = new ContractDto();
        if(contractPartyaPo.getTypeId().equals("1")){
            contractDto.setaPartyaId(contractPartyaPo.getPartyaId());
        }else if(contractPartyaPo.getTypeId().equals("2")){
            contractDto.setbPartyaId(contractPartyaPo.getPartyaId());
        }else if(contractPartyaPo.getTypeId().equals("3")){
            contractDto.setcPartyaId(contractPartyaPo.getPartyaId());
        }
        List<ContractDto> contractDtos = contractInnerServiceSMOImpl.queryContracts(contractDto);
        if(!CollectionUtils.isEmpty(contractDtos)){
            throw new IllegalArgumentException("该合同主体已经被使用,不能删除");
        }
        contractPartyaPo.setStoreId(storeId);
        return deleteContractPartyaBMOImpl.delete(contractPartyaPo);
    }
service-user/src/main/java/com/java110/user/cmd/org/ListOrgTreeCmd.java
@@ -137,7 +137,7 @@
        OrgTreeDto storeOrgTreeDto = null;
        for (OrgDto tmpOrgDto : orgDtos) {
            if (OrgDto.ORG_LEVEL_STORE.equals(tmpOrgDto.getOrgLevel())) {
                storeOrgTreeDto = new OrgTreeDto(tmpOrgDto.getOrgId(), tmpOrgDto.getOrgName(), tmpOrgDto.getParentOrgId(), tmpOrgDto.getOrgName());
                storeOrgTreeDto = new OrgTreeDto(tmpOrgDto.getOrgId(), tmpOrgDto.getOrgName(), tmpOrgDto.getParentOrgId(), tmpOrgDto.getOrgName(),tmpOrgDto.getOrgLevel());
            }
        }
@@ -159,7 +159,7 @@
                continue;
            }
            if (orgDto.getParentOrgId().equals(parentOrgDto.getId())) {//二级
                child = new OrgTreeDto(orgDto.getOrgId(), orgDto.getOrgName(), orgDto.getParentOrgId(), parentOrgDto.getAllOrgName() + " / " + orgDto.getOrgName());
                child = new OrgTreeDto(orgDto.getOrgId(), orgDto.getOrgName(), orgDto.getParentOrgId(), parentOrgDto.getAllOrgName() + " / " + orgDto.getOrgName(), orgDto.getOrgLevel());
                childs.add(child);
            }
        }
service-user/src/main/java/com/java110/user/cmd/user/UserStaffModifyCmd.java
@@ -119,6 +119,8 @@
        userDto.setTel(reqJson.getString("tel"));
        userDto.setUserFlag("1");
        userDto.setLevelCd(UserDto.LEVEL_CD_STAFF); //员工
        //一个store下面只允许一个手机号创建
        userDto.setStoreId(CmdContextUtils.getStoreId(context));
        List<UserDto> users = userInnerServiceSMOImpl.getUsers(userDto);
        if (!ListUtil.isNull(users)) {
            for (UserDto user : users) {