Преглед на файлове

Merge remote-tracking branch 'origin/master'

18118724055@163.com преди 4 дни
родител
ревизия
cf0b8a92d6

+ 11 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/MarketEmailsService.java

@@ -123,4 +123,15 @@ public interface MarketEmailsService extends MyBaseService<MarketEmailsEntity> {
       * @Author: YPZ
       * @Date: 2026/9/17 15:38
       */
+
+    /**
+     * 兜底清理:预计发送时间已超过 30 分钟、状态仍为 -1(待发送)的邮件,统一置为 -3(已取消)。
+     * <p>
+     * send() 只在 expect_send_time 落进「当前这一分钟」时投递,一旦漏过窗口(服务停机、
+     * 该分钟任务未抢到锁、客户当时处于保护/暂停等),邮件就会长期卡在待发送。
+     * 这里给 30 分钟宽限期,超时即视为作废。
+     *
+     * @return 被置为已取消的邮件条数
+     */
+    int cancelOverduePending();
 }

+ 26 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/MarketEmailsServiceImpl.java

@@ -60,6 +60,9 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
     /** 重新发送邮件时,若预计发送时间已过期,顺延的分钟数 */
     private static final int RESEND_DELAY_MINUTES = 5;
 
+    /** 待发送邮件超时未发出的清理阈值(分钟):超过该时长仍为 -1 则置为 -3 */
+    private static final int PENDING_OVERDUE_MINUTES = 30;
+
     @Resource
     private CustomerBaseService customerBaseService;
 
@@ -504,6 +507,29 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
         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 聚合)
      * 不分页:全部/已保护/营销暂停 三个 Tab 由前端在结果中过滤计数。

+ 3 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/task/MarketEmailsSendSyncTask.java

@@ -28,6 +28,9 @@ public class MarketEmailsSendSyncTask {
             //客户开启自动化后,到时间没有发送未打开邮件,再次发送
             marketEmailsService.sendAgain();
 
+            //如果超过发送时间半小时还是状态还是-1,将状态改为-3
+            marketEmailsService.cancelOverduePending();
+
 
         } catch (Exception e) {
             log.error("mkt_mail_status → market_emails 同步失败", e);

+ 2 - 2
ui/smarttrade-platform/src/components/addMarketing.vue

@@ -161,7 +161,7 @@
                     <h4><i class="fas fa-users"></i> 目标客户群</h4>
 
                     <!-- AI智能推荐 -->
-                    <div class="ai-recommend-section">
+                    <!-- <div class="ai-recommend-section">
                         <div class="ai-recommend-header">
                             <i class="fas fa-robot"></i>
                             <span>AI 智能推荐客户</span>
@@ -198,7 +198,7 @@
                                 <i class="fas fa-check-circle"></i>
                             </div>
                         </div>
-                    </div>
+                    </div> -->
 
                     <div class="advanced-filters">
                         <div class="filter-header">

+ 1 - 0
ui/smarttrade-platform/src/components/marketing/customerDetail.vue

@@ -213,6 +213,7 @@
             customers.value = []
             total.value = 0
         }else{
+            filterData.value = allData.value
             customers.value = allData.value.slice(0, 10)
             total.value = allData.value.length
         }