# OooEmailConfigServiceImpl.java

    package cloud.wconnect.frontoffice.service.oooroom.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.FunctionCons;
    import cloud.wconnect.commonlib.cons.NotifySubjectI18nCons;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.pojo.dto.UserDTO;
    import cloud.wconnect.commonlib.redis.PropertyI18nRedisService;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.service.UsergroupInternalService;
    import cloud.wconnect.commonlib.util.I18nMessageUtils;
    import cloud.wconnect.frontoffice.cons.EmailConfigCons;
    import cloud.wconnect.frontoffice.cons.oooroom.OOORoomCons;
    import cloud.wconnect.frontoffice.entity.oooroom.OooEmailConfig;
    import cloud.wconnect.frontoffice.entity.oooroom.OooEmailTarget;
    import cloud.wconnect.frontoffice.mapper.oooroom.OooEmailConfigMapper;
    import cloud.wconnect.frontoffice.pojo.dto.oooroom.OooEmailConfigDTO;
    import cloud.wconnect.frontoffice.pojo.dto.oooroom.OooEmailTargetDTO;
    import cloud.wconnect.frontoffice.pojo.dto.oooroom.OooRoomSchedulerDTO;
    import cloud.wconnect.frontoffice.service.oooroom.IOooEmailConfigService;
    import cloud.wconnect.frontoffice.service.oooroom.IOooEmailTargetService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.i18n.LocaleContextHolder;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.*;
    import java.util.stream.Collectors;

    /**
     * <p>
     * ooo 邮件配置表 服务实现类
     * </p>
     *
     * @author yyt
     * @since 2023-08-05
     */
    @DS("ratelog_manage")
    @Service
    public class OooEmailConfigServiceImpl extends ServiceImpl<OooEmailConfigMapper, OooEmailConfig> implements IOooEmailConfigService {

        @Autowired
        private IOooEmailTargetService oooEmailTargetService;
        @Autowired
        private PropertyI18nRedisService propertyI18nRedisService;
        @Autowired
        private UsergroupInternalService usergroupInternalService;
        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private I18nMessageUtils i18nMessageUtils;
        @Autowired
        private BeanMapper beanMapper;

        /**
         * 保存邮件配置
         *
         * @param propertyId 资产 id
         * @param configDTO  邮件配置
         * @return 配置 id
         * @author yyt
         * @date 2023/8/7
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public Integer save(Integer propertyId, OooEmailConfigDTO configDTO) {
            OooEmailConfig config = beanMapper.map(configDTO, OooEmailConfig.class);
            config.setPropertyId(propertyId);
            saveOrUpdate(config);

            if (configDTO.getId() > 0) {
                oooEmailTargetService.remove(new QueryWrapper<OooEmailTarget>().lambda().eq(OooEmailTarget::getConfigId,
                        configDTO.getId()));
            }

            List<OooEmailTarget> targets = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(configDTO.getToList())) {
                targets.addAll(configDTO.getToList().stream().map(item -> beanMapper.map(item, OooEmailTarget.class,
                        target -> {
                            target.setTargetType(EmailConfigCons.TARGET_TYPE_TO);
                            target.setPropertyId(propertyId);
                            target.setConfigId(config.getId());
                        })).toList());
            }
            if (CollectionUtils.isNotEmpty(configDTO.getCcList())) {
                targets.addAll(configDTO.getCcList().stream().map(item -> beanMapper.map(item, OooEmailTarget.class,
                        target -> {
                            target.setTargetType(EmailConfigCons.TARGET_TYPE_CC);
                            target.setPropertyId(propertyId);
                            target.setConfigId(config.getId());
                        })).toList());
            }
            if (CollectionUtils.isNotEmpty(targets)) {
                oooEmailTargetService.saveBatch(targets);
            }

            return config.getId();
        }

        /**
         * 查询邮件配置
         *
         * @param propertyId 资产 id
         * @param type       类型（1：报告缺失，2：未关闭房间通知）
         * @param status     状态（false：关闭，true：开启）
         * @return 邮件配置
         * @author yyt
         * @date 2024/11/20
         **/
        @Override
        public OooEmailConfig get(Integer propertyId, int type, Boolean status) {
            return getOne(new QueryWrapper<OooEmailConfig>().lambda()
                    .eq(OooEmailConfig::getPropertyId, propertyId)
                    .eq(OooEmailConfig::getType, type)
                    .eq(Objects.nonNull(status), OooEmailConfig::getStatus, status));
        }

        /**
         * 获取邮件通知默认主题
         *
         * @param propertyName 资产名称
         * @param type         类型（1：报告缺失，2：未关闭房间通知）
         * @param locale       多语言
         * @return 默认主题
         * @author yyt
         * @date 2024/11/20
         **/
        @Override
        public String getDefaultSubject(String propertyName, int type, Locale locale) {
            String title = NotifySubjectI18nCons.MISSING_REPORT;
            if (type == OooRoomSchedulerDTO.NOTIFY_NOT_CLOSED) {
                title = OOORoomCons.DEFAULT_SUBJECT;
            }
            return i18nMessageUtils.message(title, locale, i18nMessageUtils.message(FunctionCons.OOO_ROOM, locale), propertyName);
        }

        /**
         * 获取邮件配置
         *
         * @param propertyId 资产 id
         * @param type       类型（1：报告缺失，2：未关闭房间通知）
         * @return 邮件配置
         * @author yyt
         * @date 2026/1/19
         **/
        @Override
        public OooEmailConfigDTO getEmailConfigDTO(int propertyId, int type) {
            PropertyDTO propertyDTO = propertyI18nRedisService.get(propertyId);
            Locale locale = LocaleContextHolder.getLocale();
            String defaultSubject = getDefaultSubject(propertyDTO.getName(), type, locale);

            OooEmailConfig config = get(propertyId, type, null);
            if (Objects.isNull(config)) {
                return new OooEmailConfigDTO(defaultSubject);
            }

            List<OooEmailTarget> emailTargets = oooEmailTargetService.list(config.getId());
            List<Integer> userIds = emailTargets.stream().filter(item -> item.getSource() == cloud.wconnect.commonlib.cons.EmailConfigCons.SOURCE_USER)
                    .map(OooEmailTarget::getIdentityId).distinct().toList();
            List<Integer> userGroupIds = emailTargets.stream().filter(item -> item.getSource() == cloud.wconnect.commonlib.cons.EmailConfigCons.SOURCE_USERGROUP)
                    .map(OooEmailTarget::getIdentityId).distinct().toList();
            Integer tenantId = propertyDTO.getTenantId();
            Map<Integer, UserDTO> userById = userInternalService.getUserMapByIds(tenantId, userIds);
            Map<Integer, String> userGroupNameById = usergroupInternalService.getUserGroupNameByIds(tenantId, propertyId, userGroupIds);
            emailTargets.forEach(item -> {
                if (item.getSource() == cloud.wconnect.commonlib.cons.EmailConfigCons.SOURCE_USER) {
                    item.setIdentityName(userById.get(item.getIdentityId()).getName());
                    item.setEmail(userById.get(item.getIdentityId()).getEmail());
                }
                if (item.getSource() == cloud.wconnect.commonlib.cons.EmailConfigCons.SOURCE_USERGROUP) {
                    item.setIdentityName(userGroupNameById.get(item.getIdentityId()));
                }
            });

            Map<Integer, List<OooEmailTarget>> targetsByTargetType = emailTargets.stream()
                    .collect(Collectors.groupingBy(OooEmailTarget::getTargetType));
            OooEmailConfigDTO configDTO = beanMapper.map(config, OooEmailConfigDTO.class);
            configDTO.setDefaultSubject(defaultSubject);
            configDTO.setToList(beanMapper.mapList(targetsByTargetType.get(cloud.wconnect.commonlib.cons.EmailConfigCons.TARGET_TYPE_TO), OooEmailTargetDTO.class));
            configDTO.setCcList(beanMapper.mapList(targetsByTargetType.get(cloud.wconnect.commonlib.cons.EmailConfigCons.TARGET_TYPE_CC), OooEmailTargetDTO.class));
            return configDTO;
        }

    }