Ver código fonte

Merge remote-tracking branch 'origin/master'

zhujing 4 semanas atrás
pai
commit
02b50f74cc

+ 12 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/controller/MarketEmailsController.java

@@ -130,4 +130,16 @@ public class MarketEmailsController {
     public Result<Object> managementDetail(Long id) {
         return marketEmailsService.getManagementDetail(id);
     }
+
+    @GetMapping("/management-stats")
+    @ApiOperation("营销: 邮件管理弹窗-按状态统计(4 个状态计数:-3 已取消 / -2 待插入内容 / -1 待发送 / 1 已发送)")
+    public Result<Object> managementStats(Long id) {
+        return marketEmailsService.getManagementStats(id);
+    }
+
+    @PostMapping("/management-page")
+    @ApiOperation("营销: 邮件管理弹窗-按状态分页查询(按 marketingCampaignId + status)")
+    public Result<Object> managementPage(@RequestBody MarketEmailsDTO marketEmailsDTO) {
+        return marketEmailsService.getManagementPage(marketEmailsDTO);
+    }
 }

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

@@ -5,8 +5,10 @@ import com.storlead.trade.entity.MarketEmailsEntity;
 import com.storlead.trade.entity.MarketingCampaignEntity;
 import com.storlead.trade.vo.MarketEmailsCustomerVO;
 import com.storlead.trade.vo.MarketEmailsManagementVO;
+import com.storlead.trade.vo.MarketEmailsStatsVO;
 import com.storlead.framework.common.result.Result;
 import com.storlead.framework.mybatis.service.MyBaseService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springframework.scheduling.annotation.Async;
 
 import java.util.List;
@@ -65,6 +67,28 @@ public interface MarketEmailsService extends MyBaseService<MarketEmailsEntity> {
      */
     Result<Object> getManagementDetail(Long marketingCampaignId);
 
+    /**
+     * 邮件管理弹窗-按状态统计(按营销活动 id)
+     * <p>
+     * 仅统计四个核心状态:-3 已取消 / -2 待插入内容 / -1 待发送 / 1 已发送
+     * </p>
+     *
+     * @param marketingCampaignId 营销活动 id
+     * @return 四个状态的邮件数量
+     */
+    Result<Object> getManagementStats(Long marketingCampaignId);
+
+    /**
+     * 邮件管理弹窗-按状态分页查询(按营销活动 id + status)
+     * <p>
+     * 复用 getManagementDetail 的 enrichment(customerName / campaignName / stageName)。
+     * </p>
+     *
+     * @param dto 需含 marketingCampaignId、status;分页参数走 MarketEmailsDTO 继承的 Page
+     * @return 分页结果
+     */
+    Result<Object> getManagementPage(MarketEmailsDTO dto);
+
     /***
       * @Description: 通过id/marketingCampaignId/客户id关联的邮件状态
       * @Param:

+ 71 - 19
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/MarketEmailsServiceImpl.java

@@ -634,29 +634,22 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
     }
 
 
-    @Override
-    public Result<Object> getManagementDetail(Long marketingCampaignId) {
-        if (ObjectUtils.isEmpty(marketingCampaignId)) {
-            return Result.error("marketingCampaignId不能为空");
+    /**
+     * enrichment 私有方法:把 MarketEmailsEntity 列表填充 customerName / campaignName / stageName / customerContact。
+     * 供 getManagementDetail 与 getManagementPage 共用。
+     */
+    private List<MarketEmailsManagementVO> enrichManagementList(List<MarketEmailsEntity> entityList, Long marketingCampaignId) {
+        if (CollectionUtils.isEmpty(entityList)) {
+            return new ArrayList<>();
         }
 
-        // 营销活动名(用于拼接在卡片标题位置或返回顶部)
+        // 营销活动名
         String campaignName = null;
         MarketingCampaignEntity campaign = marketingCampaignService.getById(marketingCampaignId);
         if (campaign != null) {
             campaignName = campaign.getName();
         }
 
-        // 查该营销活动下所有未软删的邮件
-        LambdaQueryWrapper<MarketEmailsEntity> wrapper = new LambdaQueryWrapper<>();
-        wrapper.eq(MarketEmailsEntity::getMarketingCampaignId, marketingCampaignId);
-        wrapper.eq(MarketEmailsEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
-        wrapper.orderByAsc(MarketEmailsEntity::getExpectSendTime);
-        List<MarketEmailsEntity> entityList = this.list(wrapper);
-        if (CollectionUtils.isEmpty(entityList)) {
-            return Result.ok(new ArrayList<MarketEmailsManagementVO>());
-        }
-
         // 批量收 ID,减少 N+1
         Set<Long> customerIdSet = new HashSet<>();
         Set<Long> sopDetailIdSet = new HashSet<>();
@@ -671,10 +664,9 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
                     .collect(Collectors.toMap(CustomerEntity::getId, c -> c, (a, c) -> a));
         Map<Long, MarketingCampaignSopDetailEntity> sopDetailMap = sopDetailIdSet.isEmpty()
                 ? Collections.emptyMap()
-                : marketingCampaignSopDetailEntityService.listByIds(new java.util.ArrayList<>(sopDetailIdSet)).stream()
+                : marketingCampaignSopDetailEntityService.listByIds(new ArrayList<>(sopDetailIdSet)).stream()
                     .collect(Collectors.toMap(MarketingCampaignSopDetailEntity::getId, s -> s, (a, c) -> a));
 
-        // 组装 VO
         List<MarketEmailsManagementVO> voList = new ArrayList<>(entityList.size());
         for (MarketEmailsEntity entity : entityList) {
             MarketEmailsManagementVO vo = new MarketEmailsManagementVO();
@@ -698,7 +690,67 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
 
             voList.add(vo);
         }
-        return Result.ok(voList);
+        return voList;
+    }
+
+    @Override
+    public Result<Object> getManagementDetail(Long marketingCampaignId) {
+        if (ObjectUtils.isEmpty(marketingCampaignId)) {
+            return Result.error("marketingCampaignId不能为空");
+        }
+
+        // 查该营销活动下所有未软删的邮件
+        LambdaQueryWrapper<MarketEmailsEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(MarketEmailsEntity::getMarketingCampaignId, marketingCampaignId);
+        wrapper.eq(MarketEmailsEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
+        wrapper.orderByAsc(MarketEmailsEntity::getExpectSendTime);
+        List<MarketEmailsEntity> entityList = this.list(wrapper);
+        return Result.ok(enrichManagementList(entityList, marketingCampaignId));
+    }
+
+    @Override
+    public Result<Object> getManagementStats(Long marketingCampaignId) {
+        if (ObjectUtils.isEmpty(marketingCampaignId)) {
+            return Result.error("marketingCampaignId不能为空");
+        }
+        MarketEmailsStatsVO vo = new MarketEmailsStatsVO();
+        LambdaQueryWrapper<MarketEmailsEntity> base = new LambdaQueryWrapper<>();
+        base.eq(MarketEmailsEntity::getMarketingCampaignId, marketingCampaignId);
+        base.eq(MarketEmailsEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
+        vo.setCancelledCount(this.count(base.clone().eq(MarketEmailsEntity::getStatus, -3)));
+        vo.setPendingInsertCount(this.count(base.clone().eq(MarketEmailsEntity::getStatus, -2)));
+        vo.setPendingSendCount(this.count(base.clone().eq(MarketEmailsEntity::getStatus, -1)));
+        vo.setSentCount(this.count(base.clone().eq(MarketEmailsEntity::getStatus, 1)));
+        return Result.result(vo);
+    }
+
+    @Override
+    public Result<Object> getManagementPage(MarketEmailsDTO dto) {
+        if (dto == null || ObjectUtils.isEmpty(dto.getMarketingCampaignId())) {
+            return Result.error("marketingCampaignId不能为空");
+        }
+        if (dto.getStatus() == null) {
+            return Result.error("status不能为空");
+        }
+
+        LambdaQueryWrapper<MarketEmailsEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(MarketEmailsEntity::getMarketingCampaignId, dto.getMarketingCampaignId());
+        wrapper.eq(MarketEmailsEntity::getStatus, dto.getStatus());
+        wrapper.eq(MarketEmailsEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
+        wrapper.orderByAsc(MarketEmailsEntity::getExpectSendTime);
+
+        Page<MarketEmailsEntity> page = new Page<>(dto.getPageIndex(), dto.getPageSize());
+        IPage<MarketEmailsEntity> entityPage = this.page(page, wrapper);
+
+        // enrichment 仅作用于当前页 records
+        List<MarketEmailsManagementVO> voRecords = enrichManagementList(entityPage.getRecords(), dto.getMarketingCampaignId());
+
+        Page<MarketEmailsManagementVO> voPage = new Page<>(entityPage.getCurrent(), entityPage.getSize(), entityPage.getTotal());
+        voPage.setRecords(voRecords);
+
+
+
+        return Result.result(voPage);
     }
 
     @Override
@@ -818,7 +870,7 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
 
             Map sendMap = new HashMap();
             sendMap.put("country", country);
-            sendMap.put("beginDate", marketingCampaignEntity.getBeginData().toString());
+            sendMap.put("beginDate", marketingCampaignEntity.getBeginData() != null ? marketingCampaignEntity.getBeginData().toString() : "");
             sendMap.put("steps", sopDetailEntityString);
 
             ChatDTO chatDTO = new ChatDTO();

+ 3 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/MarketingCampaignServiceImpl.java

@@ -233,6 +233,9 @@ public class MarketingCampaignServiceImpl
     public Result<Object> addMarket(MarketingCampaignDTO marketingCampaignDTO) {
         MarketingCampaignEntity marketingCampaignEntity = new MarketingCampaignEntity();
         BeanUtils.copyProperties(marketingCampaignDTO, marketingCampaignEntity);
+        if (ObjectUtils.isEmpty(marketingCampaignEntity.getBeginData())){
+            marketingCampaignEntity.setBeginData(LocalDate.now());
+        }
         // supervisorList 转为逗号分隔字符串
         marketingCampaignEntity.setSupervisor(joinSupervisorList(marketingCampaignDTO));
         boolean isOk = this.save(marketingCampaignEntity);

+ 4 - 1
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/MarketingCampaignSopDetailServiceImpl.java

@@ -86,6 +86,7 @@ public class MarketingCampaignSopDetailServiceImpl
 //        List<CustomerEntity> customerEntityList = customerService.listByIds(customerIdList);
         //查询本地信息
         String yourName = "";
+        String companyName = "";
         String yourTitle = "";
         String yourCompany = "";
         String yourPhone = "";
@@ -97,6 +98,8 @@ public class MarketingCampaignSopDetailServiceImpl
             for (SysDictDetailResponseDTO sysDictDetailResponseDTO : sysDictDetailResponseDTOList) {
                 if ("yourName".equals(sysDictDetailResponseDTO.getLabel())) {
                     yourName = sysDictDetailResponseDTO.getValue();
+                }if ("companyName".equals(sysDictDetailResponseDTO.getLabel())) {
+                    companyName = sysDictDetailResponseDTO.getValue();
                 }
                 if ("yourTitle".equals(sysDictDetailResponseDTO.getLabel())) {
                     yourTitle = sysDictDetailResponseDTO.getValue();
@@ -134,7 +137,7 @@ public class MarketingCampaignSopDetailServiceImpl
                 if (!ObjectUtils.isEmpty(customerEntity.getCustomerCompany().getIndustry())){
                     industry = customerEntity.getCustomerCompany().getIndustry();
                 }
-                emailContent = emailContent.replace("${customerName}$", customerEntity.getCustomerName())
+                emailContent = emailContent.replace("${customerName}$", companyName)
                         .replace("${areaName}$", customerEntity.getCountry())
                         .replace("${customerIndustry}$", industry)
                         .replace("${yourName}$", yourName)

+ 35 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/vo/MarketEmailsStatsVO.java

@@ -0,0 +1,35 @@
+package com.storlead.trade.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 邮件管理弹窗-按状态统计 VO
+ * <p>
+ * 按 marketingCampaignId 统计四个核心状态下的邮件数量。
+ * </p>
+ *
+ * @author QClaw Generated
+ * @since 2026-09-15
+ */
+@Data
+@ApiModel(value = "MarketEmailsStatsVO", description = "邮件管理弹窗-按状态统计")
+public class MarketEmailsStatsVO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "已取消数量(status = -3)")
+    private Integer cancelledCount;
+
+    @ApiModelProperty(value = "待插入内容数量(status = -2)")
+    private Integer pendingInsertCount;
+
+    @ApiModelProperty(value = "待发送数量(status = -1)")
+    private Integer pendingSendCount;
+
+    @ApiModelProperty(value = "已发送数量(status = 1)")
+    private Integer sentCount;
+}