# GmwrEmailConfigServiceImpl.java

    package cloud.wconnect.workperformance.service.gmwr.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.workperformance.cons.gmwr.GmwrI18nConstant;
    import cloud.wconnect.workperformance.cons.gmwr.GmwrNotifyTypeEnum;
    import cloud.wconnect.workperformance.cons.gmwr.GmwrStatusEnum;
    import cloud.wconnect.workperformance.entity.gmwr.GmwrEmailConfig;
    import cloud.wconnect.workperformance.entity.gmwr.GmwrEmailTarget;
    import cloud.wconnect.workperformance.mapper.gmwr.GmwrEmailConfigMapper;
    import cloud.wconnect.workperformance.pojo.dto.gmwr.email.GmwrEmailConfigDTO;
    import cloud.wconnect.workperformance.pojo.dto.gmwr.email.GmwrEmailTargetDTO;
    import cloud.wconnect.workperformance.service.gmwr.IGmwrEmailConfigService;
    import cloud.wconnect.workperformance.service.gmwr.IGmwrEmailTargetService;
    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 org.springframework.transaction.annotation.Transactional;

    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>
     * Weekly GM Report 功能的邮件配置表 服务实现类
     * </p>
     *
     * @author zc
     * @since 2025-01-24
     */
    @Service
    @DS("work_performance")
    public class GmwrEmailConfigServiceImpl extends ServiceImpl<GmwrEmailConfigMapper, GmwrEmailConfig> implements IGmwrEmailConfigService {
        @Resource
        private IGmwrEmailTargetService 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 2025/1/24
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public int save(int propertyId, int operatorId, GmwrEmailConfigDTO emailConfigDTO) {
            GmwrEmailConfig emailConfig = beanMapper.map(emailConfigDTO, GmwrEmailConfig.class, config -> {
                config.setPropertyId(propertyId);
                config.setUpdateBy(operatorId);
                config.setUpdateTime(DateTimeUtils.nowTimestamp());
            });
            baseMapper.insertOrUpdateByUnique(emailConfig);

            // 删除原 Target
            emailTargetService.removeByConfigId(emailConfig.getId());

            // 保存新 Target
            List<GmwrEmailTarget> 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 资产 id
         * @param targetType 邮件类型
         * @param configId   邮件配置 id
         * @param list       EmailTargetDTO 数据
         * @return EmailTarget 集合
         * @author zc
         * @date 2025/1/24
         */
        private List<GmwrEmailTarget> convert(int propertyId, int targetType, int configId, List<GmwrEmailTargetDTO> list) {
            if (CollectionUtils.isEmpty(list)) {
                return Collections.emptyList();
            }
            return list.stream().map(item -> beanMapper.map(item, GmwrEmailTarget.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());
        }

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

            Map<Integer, List<Integer>> source2IdentityIdList = emailTargetList.stream()
                    .collect(Collectors.groupingBy(GmwrEmailTarget::getSource,
                            Collectors.mapping(GmwrEmailTarget::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<GmwrEmailTargetDTO>> targetsByTargetType = beanMapper.mapList(emailTargetList,
                    GmwrEmailTargetDTO.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(GmwrEmailTargetDTO::getTargetType));
            return beanMapper.map(emailConfig, GmwrEmailConfigDTO.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 2025/1/24
         */
        private String generateDefaultSubject(int type, String propertyName) {
            String language = LocaleContextHolder.getLocale().toString();
            String functionName = i18nMessageUtils.message(FunctionCons.GM_WEEKLY_REPORT, language);
            String statusStr = i18nMessageUtils.message(GmwrStatusEnum.getI18nCode(GmwrStatusEnum.DRAFT.getStatus()), language);
            String weekIndexStr = i18nMessageUtils.message(GmwrI18nConstant.WEEK_INDEX, language, "x");
            return i18nMessageUtils.message(GmwrNotifyTypeEnum.getDefaultSubjectI18nCode(type),
                    language, functionName, statusStr, "yyyyMM", weekIndexStr, propertyName);
        }

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