|
@@ -60,6 +60,9 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
|
|
|
/** 重新发送邮件时,若预计发送时间已过期,顺延的分钟数 */
|
|
/** 重新发送邮件时,若预计发送时间已过期,顺延的分钟数 */
|
|
|
private static final int RESEND_DELAY_MINUTES = 5;
|
|
private static final int RESEND_DELAY_MINUTES = 5;
|
|
|
|
|
|
|
|
|
|
+ /** 待发送邮件超时未发出的清理阈值(分钟):超过该时长仍为 -1 则置为 -3 */
|
|
|
|
|
+ private static final int PENDING_OVERDUE_MINUTES = 30;
|
|
|
|
|
+
|
|
|
@Resource
|
|
@Resource
|
|
|
private CustomerBaseService customerBaseService;
|
|
private CustomerBaseService customerBaseService;
|
|
|
|
|
|
|
@@ -504,6 +507,29 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
|
|
|
return Result.ok();
|
|
return Result.ok();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 兜底清理:预计发送时间已超过 {@link #PENDING_OVERDUE_MINUTES} 分钟、状态仍为 -1(待发送)的邮件,
|
|
|
|
|
+ * 统一置为 -3(已取消)。
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * send() 只在 expect_send_time 落进「当前这一分钟」时投递,一旦漏过窗口(服务停机、
|
|
|
|
|
+ * 该分钟任务没抢到锁、客户当时处于保护/暂停等),邮件就会长期卡在「待发送」。
|
|
|
|
|
+ * 这里给 30 分钟宽限期,超时即作废。一条 SQL 批量更新,不做逐条处理。
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public int cancelOverduePending() {
|
|
|
|
|
+ Date deadline = DateUtils.addMinutes(new Date(), -PENDING_OVERDUE_MINUTES);
|
|
|
|
|
+ LambdaUpdateWrapper<MarketEmailsEntity> wrapper = new LambdaUpdateWrapper<>();
|
|
|
|
|
+ wrapper.eq(MarketEmailsEntity::getStatus, -1)
|
|
|
|
|
+ .eq(MarketEmailsEntity::getIsDelete, CommonConstant.DEL_FLAG_0)
|
|
|
|
|
+ .lt(MarketEmailsEntity::getExpectSendTime, deadline)
|
|
|
|
|
+ .set(MarketEmailsEntity::getStatus, -3);
|
|
|
|
|
+ int rows = this.baseMapper.update(null, wrapper);
|
|
|
|
|
+ if (rows > 0) {
|
|
|
|
|
+ log.info("[cancelOverduePending] 超时未发出的待发送邮件已置为已取消,共{}条,deadline={}", rows, deadline);
|
|
|
|
|
+ }
|
|
|
|
|
+ return rows;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 回复邮件的客户列表(按 marketingCampaignId 过滤 + hasReply=1 + recipient 聚合)
|
|
* 回复邮件的客户列表(按 marketingCampaignId 过滤 + hasReply=1 + recipient 聚合)
|
|
|
* 不分页:全部/已保护/营销暂停 三个 Tab 由前端在结果中过滤计数。
|
|
* 不分页:全部/已保护/营销暂停 三个 Tab 由前端在结果中过滤计数。
|