|
|
@@ -8,16 +8,25 @@ import com.storlead.framework.common.constant.DSConstants;
|
|
|
import com.storlead.mail.pojo.entity.MktMailStatusEntity;
|
|
|
import com.storlead.mail.service.MktMailStatusService;
|
|
|
import com.storlead.trade.entity.MarketEmailsEntity;
|
|
|
+import com.storlead.trade.entity.MarketingCampaignEntity;
|
|
|
+import com.storlead.trade.enums.TradeMessageTypeEnum;
|
|
|
import com.storlead.trade.service.MarketEmailsService;
|
|
|
import com.storlead.trade.service.MarketEmailsStatusSyncService;
|
|
|
+import com.storlead.trade.service.MarketingCampaignService;
|
|
|
+import com.storlead.trade.service.TradeMessageAssembleService;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.HashSet;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
|
|
|
/**
|
|
|
* 跨库同步:邮件库 mkt_mail_status → 业务库 market_emails,再回写 synced_at。
|
|
|
@@ -42,6 +51,12 @@ public class MarketEmailsStatusSyncServiceImpl implements MarketEmailsStatusSync
|
|
|
@Resource
|
|
|
private MarketEmailsService marketEmailsService;
|
|
|
|
|
|
+ @Resource
|
|
|
+ private MarketingCampaignService marketingCampaignService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private TradeMessageAssembleService tradeMessageAssembleService;
|
|
|
+
|
|
|
@Override
|
|
|
public int syncOnce() {
|
|
|
int totalUpdated = 0;
|
|
|
@@ -150,9 +165,11 @@ public class MarketEmailsStatusSyncServiceImpl implements MarketEmailsStatusSync
|
|
|
changed = true;
|
|
|
}
|
|
|
//补充首次回复邮件id
|
|
|
+ boolean firstReplyMailFilled = false;
|
|
|
if (existing.getFirstReplyEmailId() == null && change.getFirstReplyEmailId() != null) {
|
|
|
update.set(MarketEmailsEntity::getFirstReplyEmailId, change.getFirstReplyEmailId());
|
|
|
changed = true;
|
|
|
+ firstReplyMailFilled = true;
|
|
|
}
|
|
|
//补充回复邮件主题
|
|
|
if (existing.getFirstReplyTheme() == null && change.getFirstReplyTheme() != null) {
|
|
|
@@ -162,7 +179,82 @@ public class MarketEmailsStatusSyncServiceImpl implements MarketEmailsStatusSync
|
|
|
if (!changed) {
|
|
|
return ApplyResult.MATCHED_NO_CHANGE;
|
|
|
}
|
|
|
- return marketEmailsService.update(update) ? ApplyResult.UPDATED : ApplyResult.MATCHED_NO_CHANGE;
|
|
|
+ boolean updated = marketEmailsService.update(update);
|
|
|
+ if (updated && firstReplyMailFilled) {
|
|
|
+ notifyCampaignSupervisor(existing, change);
|
|
|
+ }
|
|
|
+ return updated ? ApplyResult.UPDATED : ApplyResult.MATCHED_NO_CHANGE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 首次同步到回复邮件时,提醒营销活动负责人。
|
|
|
+ */
|
|
|
+ private void notifyCampaignSupervisor(MarketEmailsEntity email, MktMailStatusEntity change) {
|
|
|
+ if (email.getMarketingCampaignId() == null) {
|
|
|
+ log.warn("营销回复提醒跳过:无营销活动 id, marketEmailId={}", email.getId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ MarketingCampaignEntity campaign = marketingCampaignService.getById(email.getMarketingCampaignId());
|
|
|
+ if (campaign == null) {
|
|
|
+ log.warn("营销回复提醒跳过:活动不存在 campaignId={}", email.getMarketingCampaignId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Set<Long> toUserIds = resolveCampaignSupervisors(campaign);
|
|
|
+ if (toUserIds.isEmpty()) {
|
|
|
+ log.warn("营销回复提醒无接收人 campaignId={}", campaign.getId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Map<String, Object> payload = new HashMap<>();
|
|
|
+ payload.put("messageContent", buildFirstReplyContent(email, change, campaign));
|
|
|
+ payload.put("id", email.getEmailId());
|
|
|
+ try {
|
|
|
+ tradeMessageAssembleService.sendEventMessage(
|
|
|
+ TradeMessageTypeEnum.MKT_REPLY_NEW_MAIL.getCode(),
|
|
|
+ "MKT_REPLY_NEW_MAIL",
|
|
|
+ payload,
|
|
|
+ toUserIds);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("发送营销回复提醒失败 marketEmailId={} campaignId={}", email.getId(), campaign.getId(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Set<Long> resolveCampaignSupervisors(MarketingCampaignEntity campaign) {
|
|
|
+ Set<Long> toUserIds = new HashSet<>();
|
|
|
+ if (StringUtils.hasText(campaign.getSupervisor())) {
|
|
|
+ for (String part : campaign.getSupervisor().split(",")) {
|
|
|
+ if (!StringUtils.hasText(part)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ Long userId = Long.valueOf(part.trim());
|
|
|
+ if (userId > 0) {
|
|
|
+ toUserIds.add(userId);
|
|
|
+ }
|
|
|
+ } catch (NumberFormatException ignored) {
|
|
|
+ // skip
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (campaign.getOwnerBy() != null && campaign.getOwnerBy() > 0) {
|
|
|
+ toUserIds.add(campaign.getOwnerBy());
|
|
|
+ }
|
|
|
+ return toUserIds;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String buildFirstReplyContent(MarketEmailsEntity email, MktMailStatusEntity change,
|
|
|
+ MarketingCampaignEntity campaign) {
|
|
|
+ String from = StringUtils.hasText(email.getRecipient()) ? email.getRecipient() : "";
|
|
|
+ String subject = StringUtils.hasText(change.getFirstReplyTheme())
|
|
|
+ ? change.getFirstReplyTheme()
|
|
|
+ : (StringUtils.hasText(email.getSubject()) ? email.getSubject() : "");
|
|
|
+ String campaignName = StringUtils.hasText(campaign.getName()) ? campaign.getName() : "";
|
|
|
+ if (StringUtils.hasText(from) && StringUtils.hasText(subject)) {
|
|
|
+ return "客户【" + from + "】回复了营销邮件《" + subject + "》,请前往查看!";
|
|
|
+ }
|
|
|
+ if (StringUtils.hasText(from)) {
|
|
|
+ return "客户【" + from + "】回复了营销活动【" + campaignName + "】的邮件,请前往查看!";
|
|
|
+ }
|
|
|
+ return "营销活动【" + campaignName + "】有新的客户回复邮件,请前往查看!";
|
|
|
}
|
|
|
|
|
|
private static Integer mapSendStatus(Integer sendStatus) {
|