|
|
@@ -15,6 +15,7 @@ import com.storlead.trade.entity.MarketingCampaignEntity;
|
|
|
import com.storlead.trade.entity.SopDetailEntity;
|
|
|
import com.storlead.trade.entity.SopEntity;
|
|
|
import com.storlead.trade.mapper.SopMapper;
|
|
|
+import com.storlead.trade.vo.HotTemplateRankVO;
|
|
|
import com.storlead.trade.service.MarketingCampaignService;
|
|
|
import com.storlead.trade.service.SopDetailService;
|
|
|
import com.storlead.trade.service.SopService;
|
|
|
@@ -222,4 +223,30 @@ public class SopServiceImpl extends ServiceImpl<SopMapper, SopEntity> implements
|
|
|
|
|
|
return responsePage;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 热门模板排行:直接读 sop_detail 上统计好的 send_number / open_rate
|
|
|
+ * (由 SopDetailCountTask 每天 3 点刷新),按发送数倒序取前 N。
|
|
|
+ * 不在这里现算邮件聚合——接口高频调用,现算的成本留给定时任务更合适。
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Result<Object> hotTemplateRank(Integer limit) {
|
|
|
+ int topN = (limit == null || limit <= 0) ? 10 : Math.min(limit, 50);
|
|
|
+ LambdaQueryWrapper<SopDetailEntity> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.eq(SopDetailEntity::getIsDelete, 0);
|
|
|
+ wrapper.orderByDesc(SopDetailEntity::getSendNumber);
|
|
|
+ wrapper.orderByDesc(SopDetailEntity::getOpenRate);
|
|
|
+ wrapper.last("limit " + topN);
|
|
|
+ List<SopDetailEntity> list = sopDetailService.list(wrapper);
|
|
|
+
|
|
|
+ List<HotTemplateRankVO> voList = list.stream().map(detail -> {
|
|
|
+ HotTemplateRankVO vo = new HotTemplateRankVO();
|
|
|
+ vo.setId(detail.getId());
|
|
|
+ vo.setName(detail.getName());
|
|
|
+ vo.setSendCount(detail.getSendNumber() == null ? 0 : detail.getSendNumber());
|
|
|
+ vo.setOpenRate(detail.getOpenRate() == null ? 0 : detail.getOpenRate().intValue());
|
|
|
+ return vo;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ return Result.result(voList);
|
|
|
+ }
|
|
|
}
|