# RevenueRateFilterConfigServiceImpl.java

    package cloud.wconnect.rateshop.service.revenue.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.commonlib.util.JsonUtils;
    import cloud.wconnect.rateshop.cons.rateshop.RateTypeEnum;
    import cloud.wconnect.rateshop.entity.rateshop.Setting;
    import cloud.wconnect.rateshop.entity.revenue.RevenueRateFilterConfig;
    import cloud.wconnect.rateshop.mapper.revenue.RevenueRateFilterConfigMapper;
    import cloud.wconnect.rateshop.pojo.dto.revenue.RevenueRateFilterConfigDTO;
    import cloud.wconnect.rateshop.pojo.dto.revenue.SaveRevenueRateFilterConfigDTO;
    import cloud.wconnect.rateshop.pojo.vo.rateshop.RateConfigVO;
    import cloud.wconnect.rateshop.service.rateshop.ISettingService;
    import cloud.wconnect.rateshop.service.revenue.IRevenueRateFilterConfigService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.Collections;
    import java.util.List;
    import java.util.Map;
    import java.util.Objects;
    import java.util.stream.Collectors;

    /**
     * <p>
     * 服务实现类
     * </p>
     *
     * @author yyt
     * @since 2025-08-27
     */
    @Service
    @DS("rate_shop")
    public class RevenueRateFilterConfigServiceImpl extends ServiceImpl<RevenueRateFilterConfigMapper, RevenueRateFilterConfig> implements IRevenueRateFilterConfigService {

        @Autowired
        private ISettingService settingService;
        @Autowired
        private BeanMapper beanMapper;
        @Autowired
        private ObjectMapper objectMapper;

        /**
         * 查询房价筛选配置
         *
         * @param propertyId 资产 id
         * @return 房价筛选配置
         * @author yyt
         * @date 2025/8/27
         **/
        @Override
        public RevenueRateFilterConfig get(int propertyId) {
            return getOne(new QueryWrapper<RevenueRateFilterConfig>().lambda().eq(RevenueRateFilterConfig::getPropertyId, propertyId));
        }

        /**
         * 查询房价筛选配置
         *
         * @param propertyId 资产 id
         * @return 房价筛选配置
         * @author yyt
         * @date 2025/8/27
         **/
        @Override
        public RevenueRateFilterConfigDTO getDTO(int propertyId) {
            RevenueRateFilterConfig config = get(propertyId);
            if (config == null) {
                return new RevenueRateFilterConfigDTO();
            }

            RevenueRateFilterConfigDTO configDTO = beanMapper.map(config, RevenueRateFilterConfigDTO.class);
            Setting setting = settingService.getByPropertyId(propertyId);
            // 设置数据源/平台 是否有效
            configDTO.setDatasourceIdLastYearEffective(checkDatasourceIdLastYearEffective(setting, config));
            configDTO.setPlatformIdLastYearEffective(checkPlatformIdLastYearEffective(setting, config));
            configDTO.setDatasourceIdNextDayBarEffective(checkDatasourceIdNextDayBarEffective(setting, config));
            configDTO.setPlatformIdNextDayBarEffective(checkPlatformIdNextDayBarEffective(setting, config));
            configDTO.setDatasourceIdNextDayEbrEffective(checkDatasourceIdNextDayEbrEffective(setting, config));
            configDTO.setPlatformIdNextDayEbrEffective(checkPlatformIdNextDayEbrEffective(setting, config));
            configDTO.setDatasourceIdDailySummaryEffective(checkDatasourceIdDailySummaryEffective(setting, config));
            configDTO.setPlatformIdDailySummaryEffective(checkPlatformIdDailySummaryEffective(setting, config));
            return configDTO;
        }

        /**
         * 保存房价筛选配置
         *
         * @param propertyId                 资产 id
         * @param revenueRateFilterConfigDTO 房价筛选配置
         * @param userId                     操作人
         * @author yyt
         * @date 2025/8/27
         **/
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void save(int propertyId, SaveRevenueRateFilterConfigDTO revenueRateFilterConfigDTO, int userId) {
            RevenueRateFilterConfig config = beanMapper.map(revenueRateFilterConfigDTO, RevenueRateFilterConfig.class);
            config.setPropertyId(propertyId).setUpdatedBy(userId).setUpdatedTime(DateTimeUtils.nowTimestamp());
            baseMapper.saveOrUpdate(config);
        }

        /**
         * 检查数据源/平台，是否跟资产配置一致
         *
         * @param propertyId                 资产 id
         * @param revenueRateFilterConfigDTO 房价筛选配置
         * @return true：一致；false：不一致
         * @author yyt
         * @date 2025/8/28
         **/
        @Override
        public boolean checkDatasourceAndPlatform(int propertyId, SaveRevenueRateFilterConfigDTO revenueRateFilterConfigDTO) {
            Setting setting = settingService.getByPropertyId(propertyId);
            RevenueRateFilterConfig config = beanMapper.map(revenueRateFilterConfigDTO, RevenueRateFilterConfig.class);
            return checkDatasourceIdLastYearEffective(setting, config) && checkPlatformIdLastYearEffective(setting, config) &&
                    checkDatasourceIdNextDayBarEffective(setting, config) && checkPlatformIdNextDayBarEffective(setting, config) &&
                    checkDatasourceIdNextDayEbrEffective(setting, config) && checkPlatformIdNextDayEbrEffective(setting, config) &&
                    checkDatasourceIdDailySummaryEffective(setting, config) && checkPlatformIdDailySummaryEffective(setting, config);
        }

        /**
         * 检查 历史标准房价数据源 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         **/
        @Override
        public boolean checkDatasourceIdLastYearEffective(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            // 为空时，表示全部数据源，为有效
            if (Objects.isNull(rateFilterConfig.getDatasourceIdLastYear())) return true;

            // 当两配置都有之值时，进行比较
            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));
            return checkStandardDataSource(platformIdsByRateType, rateFilterConfig.getDatasourceIdLastYear());
        }

        /**
         * 检查 历史标准房价数据源 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         **/
        @Override
        public boolean checkDatasourceIdLastYearEffectiveForNotify(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            if (Objects.isNull(rateFilterConfig)) {
                return false;
            }

            // 当两配置都有之值时，进行比较
            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));
            return checkStandardDataSource(platformIdsByRateType, rateFilterConfig.getDatasourceIdLastYear());
        }

        /**
         * 检查 历史标准房价平台 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkPlatformIdLastYearEffective(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            // 为空时，表示全部平台，为有效
            if (Objects.isNull(rateFilterConfig.getPlatformIdLastYear())) return true;

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));
            return checkStandardPlatform(platformIdsByRateType, rateFilterConfig.getDatasourceIdLastYear(), rateFilterConfig.getPlatformIdLastYear());
        }

        /**
         * 检查 历史标准房价平台 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkPlatformIdLastYearEffectiveForNotify(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            if (Objects.isNull(rateFilterConfig)) {
                return false;
            }

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));
            return checkStandardPlatform(platformIdsByRateType, rateFilterConfig.getDatasourceIdLastYear(), rateFilterConfig.getPlatformIdLastYear());
        }

        /**
         * 检查 未来14天标准房价房价数据源 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkDatasourceIdNextDayBarEffective(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            // 为空时，表示全部数据源，为有效
            if (Objects.isNull(rateFilterConfig.getDatasourceIdNextDayBar())) return true;

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));

            return checkStandardDataSource(platformIdsByRateType, rateFilterConfig.getDatasourceIdNextDayBar());
        }

        /**
         * 检查 未来14天标准房价房价数据源 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkDatasourceIdNextDayBarEffectiveForNotify(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            if (Objects.isNull(rateFilterConfig)) {
                return false;
            }

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));

            return checkStandardDataSource(platformIdsByRateType, rateFilterConfig.getDatasourceIdNextDayBar());
        }

        /**
         * 检查 未来14天标准房价房价平台 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkPlatformIdNextDayBarEffective(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            // 为空时，表示全部平台，为有效
            if (Objects.isNull(rateFilterConfig.getPlatformIdNextDayBar())) return true;

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));
            return checkStandardPlatform(platformIdsByRateType, rateFilterConfig.getDatasourceIdNextDayBar(), rateFilterConfig.getPlatformIdNextDayBar());
        }

        /**
         * 检查 未来14天标准房价房价平台 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkPlatformIdNextDayBarEffectiveForNotify(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            if (Objects.isNull(rateFilterConfig)) {
                return false;
            }

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));
            return checkStandardPlatform(platformIdsByRateType, rateFilterConfig.getDatasourceIdNextDayBar(), rateFilterConfig.getPlatformIdNextDayBar());
        }

        /**
         * 检查 未来14天最低价数据源 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkDatasourceIdNextDayEbrEffective(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            // 为空时，表示全部数据源，为有效
            if (Objects.isNull(rateFilterConfig.getDatasourceIdNextDayEbr())) return true;

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));

            return checkLowestDataSource(platformIdsByRateType, rateFilterConfig.getDatasourceIdNextDayEbr());
        }

        /**
         * 检查 未来14天最低价数据源 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkDatasourceIdNextDayEbrEffectiveForNotify(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            if (Objects.isNull(rateFilterConfig)) {
                return false;
            }

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));

            return checkLowestDataSource(platformIdsByRateType, rateFilterConfig.getDatasourceIdNextDayEbr());
        }

        /**
         * 检查 未来14天最低价平台 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkPlatformIdNextDayEbrEffective(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            // 为空时，表示全部平台，为有效
            if (Objects.isNull(rateFilterConfig.getPlatformIdNextDayEbr())) return true;

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));

            return checkLowestPlatform(platformIdsByRateType, rateFilterConfig.getDatasourceIdNextDayEbr(), rateFilterConfig.getPlatformIdNextDayEbr());
        }

        /**
         * 检查 未来14天最低价平台 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkPlatformIdNextDayEbrEffectiveForNotify(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            if (Objects.isNull(rateFilterConfig)) {
                return false;
            }

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));

            return checkLowestPlatform(platformIdsByRateType, rateFilterConfig.getDatasourceIdNextDayEbr(), rateFilterConfig.getPlatformIdNextDayEbr());
        }

        /**
         * 检查 daily summary 数据源 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkDatasourceIdDailySummaryEffective(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            // 为空时，表示全部数据源，为有效
            if (Objects.isNull(rateFilterConfig.getDatasourceIdDailySummary())) return true;

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));

            return checkStandardDataSource(platformIdsByRateType, rateFilterConfig.getDatasourceIdDailySummary());
        }

        /**
         * 检查 daily summary 数据源 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkDatasourceIdDailySummaryEffectiveForNotify(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            if (Objects.isNull(rateFilterConfig)) {
                return false;
            }

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));

            return checkStandardDataSource(platformIdsByRateType, rateFilterConfig.getDatasourceIdDailySummary());
        }

        /**
         * 检查 daily summary 平台 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkPlatformIdDailySummaryEffective(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            // 为空时，表示全部平台，为有效
            if (Objects.isNull(rateFilterConfig.getPlatformIdDailySummary())) return true;

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));

            return checkStandardPlatform(platformIdsByRateType, rateFilterConfig.getDatasourceIdDailySummary(), rateFilterConfig.getPlatformIdDailySummary());
        }

        /**
         * 检查 daily summary 平台 是否有效
         *
         * @param setting          资产配置
         * @param rateFilterConfig 房价筛选配置
         * @return true：有效；false：无效
         * @author yyt
         * @date 2025/8/28
         */
        @Override
        public boolean checkPlatformIdDailySummaryEffectiveForNotify(Setting setting, RevenueRateFilterConfig rateFilterConfig) {
            if (Objects.isNull(rateFilterConfig)) {
                return false;
            }

            Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType = JsonUtils.convertStringToList(objectMapper, setting.getRateConfig(), RateConfigVO.class)
                    .stream().collect(Collectors.groupingBy(RateConfigVO::getRateType, Collectors.toMap(RateConfigVO::getDatasourceId, RateConfigVO::getPlatformIds)));

            return checkStandardPlatform(platformIdsByRateType, rateFilterConfig.getDatasourceIdDailySummary(), rateFilterConfig.getPlatformIdDailySummary());
        }

        /**
         * 检查标准房价数据源是否跟资产配置一致
         *
         * @param platformIdsByRateType 资产配置
         * @param datasourceId          数据源
         * @return true：一致；false：不一致
         * @author yyt
         * @date 2025/8/28
         **/
        @Override
        public boolean checkStandardDataSource(Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType, Integer datasourceId) {
            return Objects.nonNull(platformIdsByRateType.getOrDefault(RateTypeEnum.BEST_AVAILABLE_RATE.getRateType(), Collections.emptyMap()).get(datasourceId));
        }

        /**
         * 检查标准房价平台是否跟资产配置一致
         *
         * @param platformIdsByRateType 资产配置
         * @param datasourceId          数据源
         * @param platformId            平台
         * @return true：一致；false：不一致
         * @author yyt
         * @date 2025/8/28
         **/
        @Override
        public boolean checkStandardPlatform(Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType, Integer datasourceId, Integer platformId) {
            return platformIdsByRateType.getOrDefault(RateTypeEnum.BEST_AVAILABLE_RATE.getRateType(), Collections.emptyMap())
                    .getOrDefault(datasourceId, Collections.emptyList()).contains(platformId);
        }

        /**
         * 检查最低房价数据源是否跟资产配置一致
         *
         * @param platformIdsByRateType 资产配置
         * @param datasourceId          数据源
         * @return true：一致；false：不一致
         * @author yyt
         * @date 2025/8/28
         **/
        @Override
        public boolean checkLowestDataSource(Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType, Integer datasourceId) {
            return Objects.nonNull(platformIdsByRateType.getOrDefault(RateTypeEnum.EARLY_BIRD_RATE.getRateType(), Collections.emptyMap()).get(datasourceId));
        }

        /**
         * 检查最低房价平台是否跟资产配置一致
         *
         * @param platformIdsByRateType 资产配置
         * @param datasourceId          数据源
         * @param platformId            平台
         * @return true：一致；false：不一致
         * @author yyt
         * @date 2025/8/28
         **/
        @Override
        public boolean checkLowestPlatform(Map<Integer, Map<Integer, List<Integer>>> platformIdsByRateType, Integer datasourceId, Integer platformId) {
            return platformIdsByRateType.getOrDefault(RateTypeEnum.EARLY_BIRD_RATE.getRateType(), Collections.emptyMap())
                    .getOrDefault(datasourceId, Collections.emptyList()).contains(platformId);
        }

    }