# TaEmailConfigServiceImpl.java

    package cloud.wconnect.finance.service.ta.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.EmailConfigCons;
    import cloud.wconnect.commonlib.cons.FunctionCons;
    import cloud.wconnect.commonlib.pojo.bo.PropertyBO;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.pojo.dto.UserDTO;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.service.UsergroupInternalService;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.commonlib.util.I18nMessageUtils;
    import cloud.wconnect.finance.cons.ta.TaNotifyTypeEnum;
    import cloud.wconnect.finance.entity.ta.TaEmailConfig;
    import cloud.wconnect.finance.entity.ta.TaEmailTarget;
    import cloud.wconnect.finance.mapper.ta.TaEmailConfigMapper;
    import cloud.wconnect.finance.pojo.dto.ta.email.TaEmailConfigDTO;
    import cloud.wconnect.finance.pojo.dto.ta.email.TaEmailTargetDTO;
    import cloud.wconnect.finance.service.ta.ITaEmailConfigService;
    import cloud.wconnect.finance.service.ta.ITaEmailTargetService;
    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.google.common.collect.Lists;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.context.i18n.LocaleContextHolder;
    import org.springframework.stereotype.Service;

    import jakarta.annotation.Resource;

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

    /**
     * <p>
     * TA 功能的邮件配置 服务实现类
     * </p>
     *
     * @author zc
     * @since 2023-07-07
     */
    @Service
    @DS("finance")
    public class TaEmailConfigServiceImpl extends ServiceImpl<TaEmailConfigMapper, TaEmailConfig> implements ITaEmailConfigService {
        @Resource
        private ITaEmailTargetService emailTargetService;
        @Resource
        private UserInternalService userInternalService;
        @Resource
        private UsergroupInternalService usergroupInternalService;
        @Resource
        private I18nMessageUtils i18nMessageUtils;
        @Resource
        private BeanMapper beanMapper;

        /**
         * 获取邮件配置DTO
         *
         * @param propertyDTO 资产
         * @param type        邮件类型
         * @return 邮件配置数据DTO
         * @author zc
         * @date 2024/11/14
         */
        @Override
        public TaEmailConfigDTO getEmailConfigDTO(PropertyDTO propertyDTO, int type) {
            String defaultSubject = generateDefaultSubject(type, propertyDTO.getName());
            TaEmailConfig emailConfig = getEmailConfig(propertyDTO.getId(), type);
            if (Objects.isNull(emailConfig)) {
                TaEmailConfigDTO emailConfigDTO = new TaEmailConfigDTO();
                emailConfigDTO.setType(type);
                emailConfigDTO.setDefaultSubject(defaultSubject);
                return emailConfigDTO;
            }
            // 获取接收人、抄送人
            List<TaEmailTarget> emailTargetList = emailTargetService.listByConfigId(emailConfig.getId());

            Map<Integer, List<Integer>> source2IdentityIdList = emailTargetList.stream()
                    .collect(Collectors.groupingBy(TaEmailTarget::getSource,
                            Collectors.mapping(TaEmailTarget::getIdentityId, Collectors.toList())));
            // 用户
            Map<Integer, UserDTO> userId2UserDTO = userInternalService.getUserMapByIds(propertyDTO.getTenantId(),
                    source2IdentityIdList.getOrDefault(EmailConfigCons.SOURCE_USER, Collections.emptyList()));
            // 用户组
            Map<Integer, String> userGroupId2Name = usergroupInternalService.getUserGroupNameByIds(propertyDTO.getTenantId(),
                    propertyDTO.getId(), source2IdentityIdList.getOrDefault(EmailConfigCons.SOURCE_USERGROUP, Collections.emptyList()));

            //通知对象按照通知类型分组
            Map<Integer, List<TaEmailTargetDTO>> targetsByTargetType = beanMapper.mapList(emailTargetList,
                    TaEmailTargetDTO.class, (entity, dto) -> {
                        int source = dto.getSource();
                        int identityId = dto.getIdentityId();
                        switch (source) {
                            case EmailConfigCons.SOURCE_USER:
                                UserDTO userDTO = userId2UserDTO.get(identityId);
                                if (Objects.nonNull(userDTO)) {
                                    dto.setIdentityName(userDTO.getName());
                                    dto.setEmail(userDTO.getEmail());
                                }
                                break;
                            case EmailConfigCons.SOURCE_USERGROUP:
                                dto.setIdentityName(userGroupId2Name.get(identityId));
                                break;
                            case EmailConfigCons.SOURCE_MANUAL:
                                dto.setIdentityName(entity.getUsername());
                                break;
                            default:
                                break;
                        }
                    }).stream().collect(Collectors.groupingBy(TaEmailTargetDTO::getTargetType));
            return beanMapper.map(emailConfig, TaEmailConfigDTO.class, dto -> {
                dto.setDefaultSubject(defaultSubject);
                dto.setToList(targetsByTargetType.get(EmailConfigCons.TARGET_TYPE_TO));
                dto.setCcList(targetsByTargetType.get(EmailConfigCons.TARGET_TYPE_CC));
            });
        }

        /**
         * 生成邮件默认主题
         *
         * @param type         邮件类型
         * @param propertyName 资产名称
         * @return java.lang.String
         * @author zc
         * @date 2024/11/14
         */
        private String generateDefaultSubject(int type, String propertyName) {
            String language = LocaleContextHolder.getLocale().toString();
            String functionName = i18nMessageUtils.message(FunctionCons.TRAVELLIANCE_COMMISSION, language);
            return i18nMessageUtils.message(TaNotifyTypeEnum.getDefaultSubjectI18nCode(type), language, functionName, propertyName);
        }

        /**
         * 获取邮件配置
         *
         * @param propertyId 资产 id
         * @param type       邮件类型
         * @return TaEmailConfig
         * @author zc
         * @date 2024/3/17
         */
        @Override
        public TaEmailConfig getEmailConfig(int propertyId, int type) {
            return getOne(new QueryWrapper<TaEmailConfig>().lambda()
                    .eq(TaEmailConfig::getPropertyId, propertyId)
                    .eq(TaEmailConfig::getType, type));
        }

        /**
         * 保存邮件配置信息
         *
         * @param propertyId     资产 id
         * @param operatorId     操作人 id
         * @param emailConfigDTO 邮件配置信息
         * @return 邮件配置 id
         * @author zc
         * @date 2024/11/15
         */
        @Override
        public int save(int propertyId, int operatorId, TaEmailConfigDTO emailConfigDTO) {
            TaEmailConfig emailConfig = beanMapper.map(emailConfigDTO, TaEmailConfig.class, config -> {
                config.setPropertyId(propertyId);
                config.setUpdateBy(operatorId);
                config.setUpdateTime(DateTimeUtils.nowTimestamp());
            });
            baseMapper.insertOrUpdateByUnique(emailConfig);

            // 保存前先删除邮件配置接收人数据
            emailTargetService.remove(new QueryWrapper<TaEmailTarget>().lambda()
                    .eq(TaEmailTarget::getConfigId, emailConfig.getId()));

            List<TaEmailTarget> emailTargetList = Lists.newArrayList();
            emailTargetList.addAll(convert(propertyId, EmailConfigCons.TARGET_TYPE_TO, emailConfig.getId(), emailConfigDTO.getToList()));
            emailTargetList.addAll(convert(propertyId, EmailConfigCons.TARGET_TYPE_CC, emailConfig.getId(), emailConfigDTO.getCcList()));
            emailTargetService.saveBatch(emailTargetList);

            return emailConfig.getId();
        }

        /**
         * 转换为 EmailTarget 实体类对象
         *
         * @param propertyId property id
         * @param targetType 邮件类型
         * @param configId   邮件配置 id
         * @param list       EmailTargetDTO 数据
         * @return EmailTarget 集合
         * @author zc
         * @date 2024/11/14
         */
        private List<TaEmailTarget> convert(int propertyId, int targetType, int configId, List<TaEmailTargetDTO> list) {
            if (CollectionUtils.isEmpty(list)) {
                return Collections.emptyList();
            }
            return list.stream().map(item -> beanMapper.map(item, TaEmailTarget.class, target -> {
                target.setPropertyId(propertyId);
                target.setConfigId(configId);
                target.setTargetType(targetType);
                // 用户来源是 manual 时，用户 id 记录为 0，保存用户名
                if (target.getSource() == EmailConfigCons.USER_SOURCE_MANUAL) {
                    target.setIdentityId(EmailConfigCons.ZERO);
                    target.setUsername(item.getIdentityName());
                } else {
                    target.setUsername(null);
                    target.setEmail(null);
                }
            })).collect(Collectors.toList());
        }
    }