# SvaSendNotifyServiceImpl.java

    package cloud.wconnect.workperformance.service.sva.scheduleactual.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.*;
    import cloud.wconnect.commonlib.pojo.dto.*;
    import cloud.wconnect.commonlib.pojo.dto.internationalization.InternationalizationDateTimeDTO;
    import cloud.wconnect.commonlib.pojo.dto.line.PublicFlexMsgParm;
    import cloud.wconnect.commonlib.pojo.dto.line.ReportMissedMsgParm;
    import cloud.wconnect.commonlib.service.NotifyInternalService;
    import cloud.wconnect.commonlib.service.PropertyInternalService;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.util.*;
    import cloud.wconnect.workperformance.cons.FunctionPointEnum;
    import cloud.wconnect.workperformance.cons.sva.SvaNotifyTypeEnum;
    import cloud.wconnect.workperformance.entity.sva.SvaDataPermissionConfig;
    import cloud.wconnect.workperformance.entity.sva.SvaEmailConfig;
    import cloud.wconnect.workperformance.pojo.vo.sva.salesforcast.SaleForecastEmailVO;
    import cloud.wconnect.workperformance.service.sva.scheduleactual.ISvaEmailConfigService;
    import cloud.wconnect.workperformance.service.sva.scheduleactual.ISvaEmailTargetService;
    import cloud.wconnect.workperformance.service.sva.scheduleactual.ISvaSendNotifyService;
    import com.alibaba.fastjson.JSONObject;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.google.common.collect.Lists;
    import jakarta.annotation.Resource;
    import org.apache.commons.collections.CollectionUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    import org.thymeleaf.TemplateEngine;
    import org.thymeleaf.context.Context;

    import java.util.LinkedHashMap;
    import java.util.List;
    import java.util.Objects;

    /**
     * Service: 发送通知
     *
     * @author zc
     * @date 2023/12/01
     */
    @Service
    @DS("work_performance")
    public class SvaSendNotifyServiceImpl implements ISvaSendNotifyService {
        @Resource
        private ISvaEmailConfigService emailConfigService;
        @Resource
        private ISvaEmailTargetService emailTargetService;
        @Resource
        private UserInternalService userInternalService;
        @Resource
        private PropertyInternalService propertyInternalService;
        @Resource
        private LineMessageUtil lineMessageUtil;
        @Resource
        private NotifyInternalService notifyInternalService;
        @Resource
        private TemplateEngine templateEngine;
        @Resource
        private I18nMessageUtils i18nMessageUtils;
        @Resource
        private BeanMapper beanMapper;
        @Resource
        private UpdateLogUtil updateLogUtil;

        @Value("${here.link.sva.schedule-vs-actual}")
        private String link;

        /**
         * 数据权限审批通知
         *
         * @param dataPermissionConfig 数据权限
         * @author zc
         * @date 2024/10/30
         */
        @Override
        public void dataPermissionApproval(SvaDataPermissionConfig dataPermissionConfig) {
            PropertyDTO propertyDTO = propertyInternalService.getOne(dataPermissionConfig.getPropertyId());
            String language = propertyDTO.getLanguage();
            String propertyName = propertyDTO.getName();

            String hereLink = link + "?tenant=" + propertyDTO.getTenantSymbol() + "&property=" + propertyDTO.getAbbr();
            String functionName = i18nMessageUtils.message(FunctionCons.SCHEDULE_VS_ACTUAL, language);
            String approveStatus = i18nMessageUtils.message(DataPermissionStatusEnum.getI18nCode(dataPermissionConfig.getStatus()), language);
            String defaultSubject = i18nMessageUtils.message(NotifySubjectI18nCons.DATA_PERMISSION_APPROVAL, language, functionName, propertyName);
            String permissionType = i18nMessageUtils.message(CommonFieldI18nConstant.DATA_PERMISSION_READ_ONLY, language);
            List<NotifyIdentityDTO> identityDTOList = Lists.newArrayList(NotifyIdentityDTO.builder()
                    .source(EmailConfigCons.USER_SOURCE_W_CONNECT)
                    .targetType(EmailConfigCons.TARGET_TYPE_TO)
                    .identityId(dataPermissionConfig.getIdentityId()).build());

            UpdateLog lastUpdateLog = updateLogUtil.getLast(dataPermissionConfig.getUpdateLog());
            UserDTO userDTO = userInternalService.getOne(propertyDTO.getTenantId(), lastUpdateLog.getUid());

            InternationalizationDateTimeDTO dateTimeDTO = propertyDTO.getInternationalization().getDateTime();
            String applyDate = InternationalizationUtils.formatDateTime(lastUpdateLog.getTimestamp(), dateTimeDTO.getLongDate(),
                    null, propertyDTO.getTimezone(), language);

            // 邮件通知内容
            Context context = new Context();
            context.setVariable("propertyName", propertyName);
            context.setVariable("functionName", functionName);
            context.setVariable("hereLink", hereLink);
            context.setVariable("approveStatus", approveStatus);
            context.setVariable("permissionType", permissionType);
            context.setVariable("applyBy", userDTO.getName());
            context.setVariable("applyDate", applyDate);
            String processContent = templateEngine.process(EmailUtil.getDataPermissionTemplateName(language), context);
            String emailContent = EmailUtil.getFullEmailContent(defaultSubject, processContent, language);

            // LINE 通知内容
            LinkedHashMap<String, String> businessMap = new LinkedHashMap<>();
            businessMap.put(i18nMessageUtils.message(CommonFieldI18nConstant.STATUS, language), approveStatus);
            businessMap.put(i18nMessageUtils.message(CommonFieldI18nConstant.APPLY_BY, language), userDTO.getName());
            JSONObject lineMsg = lineMessageUtil.generatePublicFlexMsg(PublicFlexMsgParm.builder()
                    .propertyId(propertyDTO.getId())
                    .propertyName(propertyName)
                    .functionName(functionName)
                    .title("Data permission - approval")
                    .link(hereLink)
                    .businessMap(businessMap)
                    .build());

            // 通知DTO
            NotifyDTO notifyDTO = NotifyDTO.builder()
                    .propertyId(propertyDTO.getId())
                    .subject(defaultSubject)
                    .emailContent(emailContent)
                    .lineContent(Lists.newArrayList(lineMsg))
                    .identityList(identityDTOList)
                    .functionPoint(FunctionPointEnum.SVA_DATA_PERMISSION_APPLY.getFunctionPoint())
                    .build();

            notifyInternalService.sendNotify(notifyDTO);
        }

        /**
         * 数据权限申请通知
         *
         * @param dataPermissionConfig 数据权限
         * @author zc
         * @date 2024/10/30
         */
        @Override
        public void dataPermissionApply(SvaDataPermissionConfig dataPermissionConfig) {
            int notifyType = SvaNotifyTypeEnum.DATA_PERMISSION_APPLY.getType();
            // 获取邮件配置
            SvaEmailConfig emailConfig = emailConfigService.getEmailConfig(dataPermissionConfig.getPropertyId(), notifyType);
            if (Objects.isNull(emailConfig)) {
                return;
            }
            List<NotifyIdentityDTO> identityDTOList = emailTargetService.listByConfigId(emailConfig.getId()).stream()
                    .map(item -> beanMapper.map(item, NotifyIdentityDTO.class)).toList();
            if (CollectionUtils.isEmpty(identityDTOList)) {
                return;
            }

            PropertyDTO propertyDTO = propertyInternalService.getOne(dataPermissionConfig.getPropertyId());
            String language = propertyDTO.getLanguage();
            String propertyName = propertyDTO.getName();

            String hereLink = link + "?tenant=" + propertyDTO.getTenantSymbol() + "&property=" + propertyDTO.getAbbr();
            String functionName = i18nMessageUtils.message(FunctionCons.SCHEDULE_VS_ACTUAL, language);
            String approveStatus = i18nMessageUtils.message(DataPermissionStatusEnum.WAITING_FOR_APPROVAL.getI18nCode(), language);
            String defaultSubject = i18nMessageUtils.message(SvaNotifyTypeEnum.getDefaultSubjectI18nCode(notifyType),
                    language, functionName, propertyName);
            String subject = StringUtils.isNotBlank(emailConfig.getSubject()) ? emailConfig.getSubject() : defaultSubject;
            String permissionType = i18nMessageUtils.message(CommonFieldI18nConstant.DATA_PERMISSION_READ_ONLY, language);

            UpdateLog lastUpdateLog = updateLogUtil.getLast(dataPermissionConfig.getUpdateLog());
            String applyBy = userInternalService.getOne(propertyDTO.getTenantId(), lastUpdateLog.getUid()).getName();

            InternationalizationDateTimeDTO dateTimeDTO = propertyDTO.getInternationalization().getDateTime();
            String applyDate = InternationalizationUtils.formatDateTime(lastUpdateLog.getTimestamp(), dateTimeDTO.getLongDate(),
                    null, propertyDTO.getTimezone(), language);

            // 邮件通知内容
            Context context = new Context();
            context.setVariable("propertyName", propertyName);
            context.setVariable("functionName", functionName);
            context.setVariable("hereLink", hereLink);
            context.setVariable("approveStatus", approveStatus);
            context.setVariable("permissionType", permissionType);
            context.setVariable("applyBy", applyBy);
            context.setVariable("applyDate", applyDate);
            String processContent = templateEngine.process(EmailUtil.getDataPermissionTemplateName(language), context);
            String emailContent = EmailUtil.getFullEmailContent(defaultSubject, processContent, language);

            // LINE 通知内容
            LinkedHashMap<String, String> businessMap = new LinkedHashMap<>();
            businessMap.put(i18nMessageUtils.message(CommonFieldI18nConstant.STATUS, language), approveStatus);
            businessMap.put(i18nMessageUtils.message(CommonFieldI18nConstant.APPLY_BY, language), applyBy);
            JSONObject lineMsg = lineMessageUtil.generatePublicFlexMsg(PublicFlexMsgParm.builder()
                    .propertyId(propertyDTO.getId())
                    .propertyName(propertyName)
                    .functionName(functionName)
                    .title("Data permission - apply")
                    .link(hereLink)
                    .businessMap(businessMap)
                    .build());

            // 通知DTO
            NotifyDTO notifyDTO = NotifyDTO.builder()
                    .propertyId(propertyDTO.getId())
                    .subject(subject)
                    .emailContent(emailContent)
                    .lineContent(Lists.newArrayList(lineMsg))
                    .identityList(identityDTOList)
                    .functionPoint(FunctionPointEnum.SVA_DATA_PERMISSION_APPLY.getFunctionPoint())
                    .build();

            notifyInternalService.sendNotify(notifyDTO);
        }

        /**
         * 获取通知配置DTO
         *
         * @param propertyDTO 资产
         * @param reportName  报告名称
         * @param missDate    缺失日期
         * @param hereLink    跳转链接
         * @param notifyType  通知类型
         * @return NotifyDTO
         * @author zc
         * @date 2024/10/28
         */
        @Override
        public NotifyDTO getNotifyDTO(PropertyDTO propertyDTO, String reportName, String missDate, String hereLink, int notifyType) {
            // 获取邮件配置
            SvaEmailConfig emailConfig = emailConfigService.getEmailConfig(propertyDTO.getId(), notifyType);
            if (Objects.isNull(emailConfig)) {
                return null;
            }
            if (!emailConfig.getStatus()) {
                return null;
            }
            List<NotifyIdentityDTO> identityDTOList = emailTargetService.listByConfigId(emailConfig.getId()).stream()
                    .map(item -> beanMapper.map(item, NotifyIdentityDTO.class)).toList();
            if (CollectionUtils.isEmpty(identityDTOList)) {
                return null;
            }

            String functionName = i18nMessageUtils.message(FunctionCons.SCHEDULE_VS_ACTUAL, propertyDTO.getLanguage());
            String defaultSubject = i18nMessageUtils.message(SvaNotifyTypeEnum.getDefaultSubjectI18nCode(notifyType),
                    propertyDTO.getLanguage(), functionName, propertyDTO.getName());
            String subject = StringUtils.isNotBlank(emailConfig.getSubject()) ? emailConfig.getSubject() : defaultSubject;

            // 邮件通知内容
            Context context = new Context();
            context.setVariable("propertyName", propertyDTO.getName());
            context.setVariable("functionName", functionName);
            context.setVariable("reportName", reportName);
            context.setVariable("reportDate", missDate);
            context.setVariable("hereLink", hereLink);
            String processContent = templateEngine.process(EmailUtil.getMissReportTemplateName(propertyDTO.getLanguage()), context);
            String emailContent = EmailUtil.getFullEmailContent(defaultSubject, processContent, propertyDTO.getLanguage());

            // LINE 通知内容
            JSONObject lineMsg = lineMessageUtil.generateReportMissedMsg(ReportMissedMsgParm.builder()
                    .propertyId(propertyDTO.getId())
                    .propertyName(propertyDTO.getName())
                    .functionName(functionName)
                    .reportName(reportName)
                    .missDate(missDate)
                    .build());

            return NotifyDTO.builder()
                    .propertyId(propertyDTO.getId())
                    .subject(subject)
                    .emailContent(emailContent)
                    .lineContent(Lists.newArrayList(lineMsg))
                    .identityList(identityDTOList)
                    .functionPoint(FunctionPointEnum.SVA_MISSING_REPORT.getFunctionPoint())
                    .build();
        }

        /**
         * 获取通知配置DTO
         *
         * @param propertyDTO             资产
         * @param missDate                缺失日期
         * @param hereLink                跳转链接
         * @param saleForecastEmailVOList 数据
         * @return NotifyDTO
         * @author zc
         * @date 2024/10/29
         */
        @Override
        public NotifyDTO getNotifyDTOForSales(PropertyDTO propertyDTO, String missDate, String hereLink,
                                              List<SaleForecastEmailVO> saleForecastEmailVOList) {
            int notifyType = SvaNotifyTypeEnum.MISSING_DATA_SALES_FORECAST.getType();
            // 获取邮件配置
            SvaEmailConfig emailConfig = emailConfigService.getEmailConfig(propertyDTO.getId(), notifyType);
            if (Objects.isNull(emailConfig)) {
                return null;
            }
            if (!emailConfig.getStatus()) {
                return null;
            }
            List<NotifyIdentityDTO> identityDTOList = emailTargetService.listByConfigId(emailConfig.getId()).stream()
                    .map(item -> beanMapper.map(item, NotifyIdentityDTO.class)).toList();
            if (CollectionUtils.isEmpty(identityDTOList)) {
                return null;
            }

            String functionName = i18nMessageUtils.message(FunctionCons.SCHEDULE_VS_ACTUAL, propertyDTO.getLanguage());
            String defaultSubject = i18nMessageUtils.message(SvaNotifyTypeEnum.getDefaultSubjectI18nCode(notifyType),
                    propertyDTO.getLanguage(), functionName, propertyDTO.getName());
            String subject = StringUtils.isNotBlank(emailConfig.getSubject()) ? emailConfig.getSubject() : defaultSubject;

            // 邮件通知内容
            Context context = new Context();
            context.setVariable("propertyName", propertyDTO.getName());
            context.setVariable("functionName", functionName);
            context.setVariable("hereLink", hereLink);
            context.setVariable("dataList", saleForecastEmailVOList);
            String processContent = templateEngine.process("sva/sva-sale-forecast-data-miss_" + propertyDTO.getLanguage(), context);
            String emailContent = EmailUtil.getFullEmailContent(defaultSubject, processContent, propertyDTO.getLanguage());

            // LINE 通知内容
            LinkedHashMap<String, String> businessMap = new LinkedHashMap<>();
            businessMap.put(i18nMessageUtils.message(CommonFieldI18nConstant.TOTAL, propertyDTO.getLanguage()), Integer.valueOf(saleForecastEmailVOList.size()).toString());
            JSONObject lineMsg = lineMessageUtil.generatePublicFlexMsg(PublicFlexMsgParm.builder()
                    .propertyId(propertyDTO.getId())
                    .propertyName(propertyDTO.getName())
                    .functionName(functionName)
                    .title("Missing data")
                    .link(hereLink)
                    .businessMap(businessMap)
                    .build());

            return NotifyDTO.builder()
                    .propertyId(propertyDTO.getId())
                    .subject(subject)
                    .emailContent(emailContent)
                    .lineContent(Lists.newArrayList(lineMsg))
                    .identityList(identityDTOList)
                    .functionPoint(FunctionPointEnum.SVA_MISSING_REPORT.getFunctionPoint())
                    .build();
        }
    }