Ver Fonte

Merge remote-tracking branch 'origin/master'

18118724055@163.com há 2 semanas atrás
pai
commit
a6bc705ff6

+ 16 - 4
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/MarketEmailsServiceImpl.java

@@ -459,11 +459,21 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
                 if (vo.getId() == null && e.getId() != null) {
                     vo.setId(e.getId());
                 }
-                // 取最早的 firstReplyTime + 同时记录主题/emailId
+                // 取最早的 firstReplyTime
                 if (e.getFirstReplyTime() != null) {
                     if (vo.getFirstReplyTime() == null || e.getFirstReplyTime().before(vo.getFirstReplyTime())) {
                         vo.setFirstReplyTime(e.getFirstReplyTime());
-                        vo.setReplyContent(e.getFirstReplyTheme());
+                    }
+                }
+                // 取最新且非空的回复主题(bestReplyContent 聚合)
+                String theme = e.getFirstReplyTheme();
+                if (theme != null && !theme.trim().isEmpty()) {
+                    if (vo.getBestReplyContent() == null) {
+                        vo.setBestReplyContent(theme);
+                    } else if (e.getFirstReplyTime() != null
+                            && (vo.getFirstReplyTime() == null || e.getFirstReplyTime().after(vo.getFirstReplyTime()))) {
+                        // 当前记录的 firstReplyTime 比已记录的 firstReplyTime 更新时,更新 bestReplyContent
+                        vo.setBestReplyContent(theme);
                     }
                 }
                 // MAX(has_protect) / MAX(has_suspend) 语义
@@ -475,10 +485,12 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
                 }
             }
         }
-        // 默认未保护/未暂停为 0
+        // 默认未保护/未暂停为 0;bestReplyContent 写回 replyContent
         for (com.storlead.trade.vo.MarketEmailsReplyVO vo : aggMap.values()) {
             if (vo.getHasProtect() == null) vo.setHasProtect(0);
             if (vo.getHasSuspend() == null) vo.setHasSuspend(0);
+            vo.setReplyContent(vo.getBestReplyContent());
+            vo.setBestReplyContent(null);
         }
         // 按首次回复时间倒序(最近回复的排前)
         List<com.storlead.trade.vo.MarketEmailsReplyVO> voList = new java.util.ArrayList<>(aggMap.values());
@@ -492,7 +504,7 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
         // 批量回填:客户名 / 客户等级 / 核心标签
         if (!voList.isEmpty()) {
             java.util.Set<Long> customerIdSet = new java.util.LinkedHashSet<>();
-            for (com.storlead.trade.vo.MarketEmailsReplyVO v : voList) {
+            for (MarketEmailsReplyVO v : voList) {
                 if (v.getCustomerId() != null) customerIdSet.add(v.getCustomerId());
             }
             if (!customerIdSet.isEmpty()) {

+ 2 - 1
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/MarketingCampaignServiceImpl.java

@@ -329,7 +329,7 @@ public class MarketingCampaignServiceImpl
         Integer emailCountLong = marketEmailsService.lambdaQuery()
                 .eq(MarketEmailsEntity::getMarketingCampaignId, id)
                 .eq(MarketEmailsEntity::getIsDelete, CommonConstant.DEL_FLAG_0)
-//                .eq(MarketEmailsEntity::getStatus, 1)
+                .eq(MarketEmailsEntity::getHasFirst, 1)
                 .count();
         Integer emailCount = emailCountLong == null ? 0 : emailCountLong.intValue();
         stats.setEmailCount(emailCount);
@@ -338,6 +338,7 @@ public class MarketingCampaignServiceImpl
                 .eq(MarketEmailsEntity::getMarketingCampaignId, id)
                 .eq(MarketEmailsEntity::getIsDelete, CommonConstant.DEL_FLAG_0)
                 .eq(MarketEmailsEntity::getStatus, 1)
+                .eq(MarketEmailsEntity::getHasFirst, 1)
                 .count();
         Integer sentCount = sentCountLong == null ? 0 : sentCountLong.intValue();
         stats.setSentCount(sentCount);

+ 16 - 2
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/MarketingCampaignSopDetailServiceImpl.java

@@ -50,6 +50,19 @@ public class MarketingCampaignSopDetailServiceImpl
         if (ObjectUtils.isEmpty(dto.getId())) {
             return Result.error("id不能为空");
         }
+
+        //先判断这个sopDetail中是否有关联已发送的邮件,如果有,不能进行修改
+        LambdaQueryWrapper<MarketEmailsEntity> marketEmailsEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        marketEmailsEntityLambdaQueryWrapper.eq(MarketEmailsEntity::getMarketingCampaignSopDetailId, dto.getId());
+        marketEmailsEntityLambdaQueryWrapper.eq(MarketEmailsEntity::getMarketingCampaignId, dto.getMarketingCampaignId());
+        marketEmailsEntityLambdaQueryWrapper.eq(MarketEmailsEntity::getStatus, 1);
+        marketEmailsEntityLambdaQueryWrapper.eq(MarketEmailsEntity::getIsDelete, 0);
+        List<MarketEmailsEntity> marketEmailsEntityList = marketEmailsService.list(marketEmailsEntityLambdaQueryWrapper);
+        if (!CollectionUtils.isEmpty(marketEmailsEntityList)) {
+            return Result.error("存在已发送的邮件,不能进行修改");
+        }
+
+
         MarketingCampaignSopDetailEntity entity = new MarketingCampaignSopDetailEntity();
         BeanUtils.copyProperties(dto, entity);
         boolean isOk = this.updateById(entity);
@@ -58,16 +71,17 @@ public class MarketingCampaignSopDetailServiceImpl
         }
         if (!ObjectUtils.isEmpty(dto.getEmailContent())){
             //写入每个客户的邮件内容
-            this.updateEmailContent(dto.getId(),dto.getEmailSubject(), dto.getEmailContent());
+            this.updateEmailContent(dto.getId(),dto.getEmailSubject(), dto.getEmailContent(), dto.getMarketingCampaignId());
         }
         return Result.result(entity);
     }
 
-    private void updateEmailContent(Long id, String emailSubject, String emailContent) {
+    private void updateEmailContent(Long id, String emailSubject, String emailContent, Long marketingCampaignId) {
         //查询营销活动关联的所有客户
 //        MarketingCampaignSopDetailEntity entity = this.getById(id);
         LambdaQueryWrapper<MarketEmailsEntity> marketEmailsEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
         marketEmailsEntityLambdaQueryWrapper.eq(MarketEmailsEntity::getMarketingCampaignSopDetailId, id);
+        marketEmailsEntityLambdaQueryWrapper.eq(MarketEmailsEntity::getMarketingCampaignId, marketingCampaignId);
         marketEmailsEntityLambdaQueryWrapper.eq(MarketEmailsEntity::getIsDelete, 0);
         List<MarketEmailsEntity> marketEmailsEntityList = marketEmailsService.list(marketEmailsEntityLambdaQueryWrapper);
 

+ 3 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/vo/MarketEmailsReplyVO.java

@@ -65,6 +65,9 @@ public class MarketEmailsReplyVO implements Serializable {
     @ApiModelProperty(value = "回复内容(复用 first_reply_theme 字段,DB 未单独建 reply_content)")
     private String replyContent;
 
+    @ApiModelProperty(value = "临时字段:用于聚合时记录最佳回复主题(最新且非空),聚合结束后写入 replyContent,不暴露给前端")
+    private String bestReplyContent;
+
     @ApiModelProperty(value = "是否保护(0未保护、1保护)")
     private Integer hasProtect;
 

+ 2 - 1
ui/smarttrade-platform/src/components/marketing/aiGenerator.vue

@@ -401,12 +401,13 @@
             id: typeData.value.filter(item => item.name == aiGenerator.value.inputs.scene)[0].id,
             emailContent: emailContent.value,
             emailSubject: emailSubject.value,
+            marketingCampaignId: marketingData.value.id
         }
         saveGenerateEmail(params).then(res => {
             ElMessage.success('保存成功')
             showAIModal.value = false
         }).catch(err => {
-            ElMessage.error('保存失败')
+            ElMessage.error(err.message || '保存失败')
         })
     }
 

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

@@ -105,7 +105,7 @@
           ElMessage.success('操作成功')
           emits('refresh')
         }).catch(err => {
-          ElMessage.error('操作失败')
+          ElMessage.error(err.message ||'操作失败')
         })
       })
     }

+ 2 - 2
ui/smarttrade-platform/src/components/marketing/openedCustomers.vue

@@ -115,7 +115,7 @@
           ElMessage.success('操作成功')
           emits('refresh')
         }).catch(err => {
-          ElMessage.error('操作失败')
+          ElMessage.error(err.message || '操作失败')
         })
       })
     }
@@ -139,7 +139,7 @@
           ElMessage.success('操作成功')
           emits('refresh')
         }).catch(err => {
-          ElMessage.error('操作失败')
+          ElMessage.error(err.message || '操作失败')
         })
       })
     }

+ 2 - 2
ui/smarttrade-platform/src/components/marketing/replyCustomers.vue

@@ -114,7 +114,7 @@
           ElMessage.success('操作成功')
           emits('refresh')
         }).catch(err => {
-          ElMessage.error('操作失败')
+          ElMessage.error(err.message ||'操作失败')
         })
       })
     }
@@ -138,7 +138,7 @@
           ElMessage.success('操作成功')
           emits('refresh')
         }).catch(err => {
-          ElMessage.error('操作失败')
+          ElMessage.error(err.message || '操作失败')
         })
       })
     }

+ 1 - 1
ui/smarttrade-platform/src/views/MarketingView.vue

@@ -134,7 +134,7 @@
               <img src="../assets/images/email-list.svg" />{{ campaign.emailCountStats }}
             </button>
           </div>
-          <button class="btn btn-secondary btn-sm" @click="changeStatus(campaign)" :title="campaign.status == 1 ? '暂停' : '开始'">
+          <button v-if="campaign.status != 3" class="btn btn-secondary btn-sm" @click="changeStatus(campaign)" :title="campaign.status == 1 ? '暂停' : '开始'">
             <img v-if="campaign.status == 1" src="../assets/images/marketing-pause.svg" />
             <img v-else src="../assets/images/marketing-start.svg" />
           </button>