# ClcEmailConfigServiceImpl.java

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

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.FunctionCons;
    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.clc.CLCNotifyEnum;
    import cloud.wconnect.frontoffice.entity.clc.ClcEmailConfig;
    import cloud.wconnect.frontoffice.entity.clc.ClcEmailTarget;
    import cloud.wconnect.frontoffice.mapper.clc.ClcEmailConfigMapper;
    import cloud.wconnect.frontoffice.pojo.dto.clc.ClcEmailConfigDTO;
    import cloud.wconnect.frontoffice.pojo.dto.clc.ClcEmailTargetDTO;
    import cloud.wconnect.frontoffice.service.clc.IClcEmailConfigService;
    import cloud.wconnect.frontoffice.service.clc.IClcEmailTargetService;
    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>
     * clc 邮件配置表 服务实现类
     * </p>
     *
     * @author yyt
     * @since 2023-07-24
     */
    @Service
    @DS("logbook")
    public class ClcEmailConfigServiceImpl extends ServiceImpl<ClcEmailConfigMapper, ClcEmailConfig> implements IClcEmailConfigService {

        @Autowired
        private IClcEmailTargetService clcEmailTargetService;
        @Autowired
        private PropertyI18nRedisService propertyI18nRedisService;
        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private UsergroupInternalService usergroupInternalService;
        @Autowired
        private I18nMessageUtils i18nMessageUtils;
        @Autowired
        private BeanMapper beanMapper;

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

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

            List<ClcEmailTarget> targets = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(configDTO.getToList())) {
                targets.addAll(configDTO.getToList().stream().map(item -> beanMapper.map(item, ClcEmailTarget.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, ClcEmailTarget.class,
                        target -> {
                            target.setTargetType(EmailConfigCons.TARGET_TYPE_CC);
                            target.setPropertyId(propertyId);
                            target.setConfigId(config.getId());
                        })).toList());
            }
            if (CollectionUtils.isNotEmpty(targets)) {
                clcEmailTargetService.saveBatch(targets);
            }

            return config.getId();
        }

        /**
         * 获取邮件通知默认主题
         *
         * @param propertyName 资产名称
         * @param type         类型 (1：arrival 报告缺失，2：missing 状态通知，3：通知酒店处理 clc 平台顾客退房，4：guest in house 报告缺失）
         * @param locale       多语言
         * @return 默认主题
         * @author yyt
         * @date 2024/11/18
         **/
        @Override
        public String getDefaultSubject(String propertyName, int type, Locale locale) {
            return i18nMessageUtils.message(CLCNotifyEnum.getI18nCode(type), locale,
                    i18nMessageUtils.message(FunctionCons.CLC_LIST, locale), propertyName);
        }

        /**
         * 获取邮件通知默认主题
         *
         * @param propertyId 资产 id
         * @param type       类型 (1：arrival 报告缺失，2：missing 状态通知，3：通知酒店处理 clc 平台顾客退房，4：guest in house 报告缺失）
         * @return 默认主题
         * @author yyt
         * @date 2024/11/18
         **/
        @Override
        public String getDefaultSubject(Integer propertyId, int type) {
            PropertyDTO propertyDTO = propertyI18nRedisService.get(propertyId);
            String language = propertyDTO.getLanguage();
            return i18nMessageUtils.message(CLCNotifyEnum.getI18nCode(type), language,
                    i18nMessageUtils.message(FunctionCons.CLC_LIST, language), propertyDTO.getName());
        }

        /**
         * 查询邮件配置
         *
         * @param propertyId 资产 id
         * @param type       类型 1：arrival 报告缺失，2：missing 状态通知，3：通知酒店处理 clc 平台顾客退房，4：guest in house 报告缺失）
         * @return 邮件配置
         * @author yyt
         * @date 2024/11/18
         **/
        @Override
        public ClcEmailConfig getOne(Integer propertyId, int type) {
            return getOne(new QueryWrapper<ClcEmailConfig>()
                    .lambda().eq(ClcEmailConfig::getPropertyId, propertyId)
                    .eq(ClcEmailConfig::getType, type));
        }

        /**
         * 获取邮件配置
         *
         * @param propertyId 资产 id
         * @param type       类型
         * @return 邮件配置
         * @author yyt
         * @date 2026/1/19
         **/
        @Override
        public ClcEmailConfigDTO getEmailConfigDTO(int propertyId, int type) {
            PropertyDTO propertyDTO = propertyI18nRedisService.get(propertyId);
            Locale locale = LocaleContextHolder.getLocale();
            String defaultSubject = getDefaultSubject(propertyDTO.getName(), type, locale);
            ClcEmailConfig config = getOne(propertyId, type);
            if (Objects.isNull(config)) {
                return new ClcEmailConfigDTO(defaultSubject);
            }

            List<ClcEmailTarget> emailTargets = clcEmailTargetService.list(config.getId());

            List<Integer> userIds = emailTargets.stream().filter(item -> item.getSource() == cloud.wconnect.commonlib.cons.EmailConfigCons.SOURCE_USER)
                    .map(ClcEmailTarget::getIdentityId).distinct().toList();
            List<Integer> userGroupIds = emailTargets.stream().filter(item -> item.getSource() == cloud.wconnect.commonlib.cons.EmailConfigCons.SOURCE_USERGROUP)
                    .map(ClcEmailTarget::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<ClcEmailTarget>> targetsByTargetType = emailTargets.stream()
                    .collect(Collectors.groupingBy(ClcEmailTarget::getTargetType));
            ClcEmailConfigDTO configDTO = beanMapper.map(config, ClcEmailConfigDTO.class);
            configDTO.setDefaultSubject(defaultSubject);
            configDTO.setToList(beanMapper.mapList(targetsByTargetType.get(cloud.wconnect.commonlib.cons.EmailConfigCons.TARGET_TYPE_TO), ClcEmailTargetDTO.class));
            configDTO.setCcList(beanMapper.mapList(targetsByTargetType.get(cloud.wconnect.commonlib.cons.EmailConfigCons.TARGET_TYPE_CC), ClcEmailTargetDTO.class));
            return configDTO;
        }

    }