# PastReservationEmailConfigServiceImpl.java

    package cloud.wconnect.frontoffice.service.pastreservation.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.pastreservation.PastReservationNotifyEnum;
    import cloud.wconnect.frontoffice.entity.pastreservation.PastReservationEmailConfig;
    import cloud.wconnect.frontoffice.entity.pastreservation.PastReservationEmailTarget;
    import cloud.wconnect.frontoffice.mapper.pastreservation.PastReservationEmailConfigMapper;
    import cloud.wconnect.frontoffice.pojo.dto.pastreservation.PastReservationEmailConfigDTO;
    import cloud.wconnect.frontoffice.pojo.dto.pastreservation.PastReservationEmailTargetDTO;
    import cloud.wconnect.frontoffice.service.pastreservation.IPastReservationEmailConfigService;
    import cloud.wconnect.frontoffice.service.pastreservation.IPastReservationEmailTargetService;
    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>
     * 邮件配置表 服务实现类
     * </p>
     *
     * @author yyt
     * @since 2024-10-01
     */
    @Service
    @DS("logbook")
    public class PastReservationEmailConfigServiceImpl extends ServiceImpl<PastReservationEmailConfigMapper, PastReservationEmailConfig> implements IPastReservationEmailConfigService {

        @Autowired
        private IPastReservationEmailTargetService emailTargetService;
        @Autowired
        private PropertyI18nRedisService propertyI18nRedisService;
        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private UsergroupInternalService usergroupInternalService;
        @Autowired
        private BeanMapper beanMapper;
        @Autowired
        private I18nMessageUtils i18nMessageUtils;

        /**
         * 保存邮件配置
         *
         * @param propertyId 资产 id
         * @param configDTO  邮件配置
         * @return 配置 id
         * @author yyt
         * @date 2024/10/2
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public Integer save(Integer propertyId, PastReservationEmailConfigDTO configDTO) {
            PastReservationEmailConfig config = beanMapper.map(configDTO, PastReservationEmailConfig.class);
            config.setPropertyId(propertyId);
            saveOrUpdate(config);

            Integer configId = config.getId();

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

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

            return configId;
        }

        /**
         * 获取邮件通知默认主题
         *
         * @param propertyName 资产名称
         * @param type         类型
         * @param locale       多语言
         * @return 默认主题
         * @author yyt
         * @date 2024/12/3
         **/
        @Override
        public String getDefaultSubject(String propertyName, Integer type, Locale locale) {
            return i18nMessageUtils.message(PastReservationNotifyEnum.getI18nCode(type), locale,
                    i18nMessageUtils.message(FunctionCons.PAST_RESERVATION, locale), propertyName);
        }

        /**
         * 获取邮件通知默认主题
         *
         * @param propertyId 资产 id
         * @param type       类型
         * @return 默认主题
         * @author yyt
         * @date 2024/12/3
         **/
        @Override
        public String getDefaultSubject(Integer propertyId, int type) {
            PropertyDTO propertyDTO = propertyI18nRedisService.get(propertyId);
            String language = propertyDTO.getLanguage();
            return i18nMessageUtils.message(PastReservationNotifyEnum.getI18nCode(type), language,
                    i18nMessageUtils.message(FunctionCons.PAST_RESERVATION, language), propertyDTO.getName());
        }

        /**
         * 查询邮件配置
         *
         * @param propertyId 资产 id
         * @param type       类型
         * @param status     状态（false：关闭，true：开启）
         * @return 邮件配置
         * @author yyt
         * @date 2024/12/3
         **/
        @Override
        public PastReservationEmailConfig get(Integer propertyId, int type, Boolean status) {
            return getOne(new QueryWrapper<PastReservationEmailConfig>().lambda()
                    .eq(PastReservationEmailConfig::getPropertyId, propertyId)
                    .eq(PastReservationEmailConfig::getType, type)
                    .eq(Objects.nonNull(status), PastReservationEmailConfig::getStatus, status));
        }

        /**
         * 获取邮件配置
         *
         * @param tenantId   租户 id
         * @param propertyId 资产 id
         * @param type       类型
         * @return 邮件配置
         * @author yyt
         * @date 2026/1/19
         **/
        @Override
        public PastReservationEmailConfigDTO getEmailConfigDTO(int tenantId, int propertyId, int type) {
            PropertyDTO propertyDTO = propertyI18nRedisService.get(propertyId);
            Locale locale = LocaleContextHolder.getLocale();
            String defaultSubject = getDefaultSubject(propertyDTO.getName(), type, locale);

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

            List<PastReservationEmailTarget> emailTargets = emailTargetService.list(config.getId());

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

    }