# WeeklyMonthlyRevenueEmailConfigServiceImpl.java

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

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.EmailConfigCons;
    import cloud.wconnect.commonlib.cons.FunctionCons;
    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.rateshop.cons.weeklymonthlyrevenue.MonthlyRevenueNotifyTypeEnum;
    import cloud.wconnect.rateshop.entity.weeklymonthlyrevenue.WeeklyMonthlyRevenueEmailConfig;
    import cloud.wconnect.rateshop.entity.weeklymonthlyrevenue.WeeklyMonthlyRevenueEmailTarget;
    import cloud.wconnect.rateshop.mapper.weeklymonthlyrevenue.WeeklyMonthlyRevenueEmailConfigMapper;
    import cloud.wconnect.rateshop.pojo.dto.weeklymonthlyrevenue.WeeklyMonthlyRevenueEmailConfigDTO;
    import cloud.wconnect.rateshop.pojo.dto.weeklymonthlyrevenue.WeeklyMonthlyRevenueEmailTargetDTO;
    import cloud.wconnect.rateshop.service.weeklymonthlyrevenue.IWeeklyMonthlyRevenueEmailConfigService;
    import cloud.wconnect.rateshop.service.weeklymonthlyrevenue.IWeeklyMonthlyRevenueEmailTargetService;
    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 jakarta.annotation.Resource;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.context.i18n.LocaleContextHolder;
    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>
     * Weekly Monthly Revenue email config 服务实现类
     * </p>
     *
     * @author zc
     * @since 2024-05-13
     */
    @Service
    @DS("rate_shop")
    public class WeeklyMonthlyRevenueEmailConfigServiceImpl extends ServiceImpl<WeeklyMonthlyRevenueEmailConfigMapper, WeeklyMonthlyRevenueEmailConfig> implements IWeeklyMonthlyRevenueEmailConfigService {
        @Resource
        private IWeeklyMonthlyRevenueEmailTargetService emailTargetService;
        @Resource
        private UserInternalService userInternalService;
        @Resource
        private UsergroupInternalService usergroupInternalService;
        @Resource
        private I18nMessageUtils i18nMessageUtils;
        @Resource
        private BeanMapper beanMapper;

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

            // 删除原有数据
            emailTargetService.removeByConfigId(emailConfig.getId());

            List<WeeklyMonthlyRevenueEmailTarget> 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();
        }

        /**
         * 转换为实体类对象
         *
         * @param propertyId property id
         * @param targetType 邮件类型
         * @param configId   邮件配置 id
         * @param list       EmailTargetDTO 数据
         * @return EmailTarget 集合
         * @author zc
         * @date 2024/11/12
         */
        private List<WeeklyMonthlyRevenueEmailTarget> convert(int propertyId, int targetType, int configId, List<WeeklyMonthlyRevenueEmailTargetDTO> list) {
            if (CollectionUtils.isEmpty(list)) {
                return Collections.emptyList();
            }
            return list.stream().map(item -> beanMapper.map(item, WeeklyMonthlyRevenueEmailTarget.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());
        }

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

            Map<Integer, List<Integer>> source2IdentityIdList = emailTargetList.stream()
                    .collect(Collectors.groupingBy(WeeklyMonthlyRevenueEmailTarget::getSource,
                            Collectors.mapping(WeeklyMonthlyRevenueEmailTarget::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<WeeklyMonthlyRevenueEmailTargetDTO>> targetsByTargetType = beanMapper.mapList(emailTargetList,
                    WeeklyMonthlyRevenueEmailTargetDTO.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(WeeklyMonthlyRevenueEmailTargetDTO::getTargetType));
            return beanMapper.map(emailConfig, WeeklyMonthlyRevenueEmailConfigDTO.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/12
         */
        private String generateDefaultSubject(int type, String propertyName) {
            String language = LocaleContextHolder.getLocale().toString();
            String functionName = i18nMessageUtils.message(FunctionCons.WEEKLY_MONTHLY_REVENUE, language);
            return i18nMessageUtils.message(MonthlyRevenueNotifyTypeEnum.getDefaultSubjectI18nCode(type), language, functionName, propertyName);
        }

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