|
|
@@ -39,6 +39,8 @@ import org.springframework.util.CollectionUtils;
|
|
|
import org.springframework.util.ObjectUtils;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
import java.time.LocalDate;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.ZoneId;
|
|
|
@@ -1052,6 +1054,64 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
|
|
|
return Result.result(list);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public Result<Map<Long, Object>> getAccountStats(List<Long> outboxIds) {
|
|
|
+ Map<Long, Object> result = new LinkedHashMap<>();
|
|
|
+ if (CollectionUtils.isEmpty(outboxIds)) {
|
|
|
+ return Result.result(result);
|
|
|
+ }
|
|
|
+ List<Long> ids = outboxIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
|
|
|
+ if (ids.isEmpty()) {
|
|
|
+ return Result.result(result);
|
|
|
+ }
|
|
|
+ for (Long id : ids) {
|
|
|
+ result.put(id, emptyAccountStats(id));
|
|
|
+ }
|
|
|
+
|
|
|
+ QueryWrapper<MarketEmailsEntity> qw = new QueryWrapper<>();
|
|
|
+ qw.select(
|
|
|
+ "outbox_id",
|
|
|
+ "COUNT(*) AS send_count",
|
|
|
+ "COUNT(CASE WHEN IFNULL(has_reply, 0) = 1 THEN 1 END) AS reply_count",
|
|
|
+ "MAX(expect_send_time) AS last_send_time");
|
|
|
+ qw.eq("is_delete", CommonConstant.DEL_FLAG_0);
|
|
|
+ qw.eq("status", 1);
|
|
|
+ qw.in("outbox_id", ids);
|
|
|
+ qw.groupBy("outbox_id");
|
|
|
+ List<Map<String, Object>> rows = this.listMaps(qw);
|
|
|
+ if (CollectionUtils.isEmpty(rows)) {
|
|
|
+ return Result.result(result);
|
|
|
+ }
|
|
|
+ for (Map<String, Object> row : rows) {
|
|
|
+ if (row == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Long id = toLongOrNull(row.get("outbox_id"));
|
|
|
+ if (id == null || !result.containsKey(id)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ MarketEmailsAccountStatsVO vo = new MarketEmailsAccountStatsVO();
|
|
|
+ int sendCount = toInteger(row.get("send_count"));
|
|
|
+ int replyCount = toInteger(row.get("reply_count"));
|
|
|
+ vo.setOutboxId(id);
|
|
|
+ vo.setSendCount(sendCount);
|
|
|
+ vo.setReplyCount(replyCount);
|
|
|
+ vo.setReplyRate(toReplyRate(sendCount, replyCount));
|
|
|
+ vo.setLastSendTime(toDate(row.get("last_send_time")));
|
|
|
+ result.put(id, vo);
|
|
|
+ }
|
|
|
+ return Result.result(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ private MarketEmailsAccountStatsVO emptyAccountStats(Long outboxId) {
|
|
|
+ MarketEmailsAccountStatsVO vo = new MarketEmailsAccountStatsVO();
|
|
|
+ vo.setOutboxId(outboxId);
|
|
|
+ vo.setSendCount(0);
|
|
|
+ vo.setReplyCount(0);
|
|
|
+ vo.setReplyRate(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP));
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 分组键转 yyyy-MM-dd:JDBC 可能返回 java.sql.Date / java.sql.Timestamp / 字符串。
|
|
|
* java.sql.Date#toInstant 会抛 UnsupportedOperationException,必须优先判断。
|
|
|
@@ -1087,6 +1147,37 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /** 聚合字段转 Long,空值保持 null。 */
|
|
|
+ private Long toLongOrNull(Object value) {
|
|
|
+ if (value == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if (value instanceof Number) {
|
|
|
+ return ((Number) value).longValue();
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ return Long.valueOf(value.toString().trim());
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private Date toDate(Object value) {
|
|
|
+ if (value instanceof Date) {
|
|
|
+ return (Date) value;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private BigDecimal toReplyRate(int sendCount, int replyCount) {
|
|
|
+ if (sendCount <= 0) {
|
|
|
+ return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
|
|
|
+ }
|
|
|
+ return BigDecimal.valueOf(replyCount)
|
|
|
+ .multiply(BigDecimal.valueOf(100))
|
|
|
+ .divide(BigDecimal.valueOf(sendCount), 2, RoundingMode.HALF_UP);
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void updateCustomerEmailStatus(MarketEmailsCustomerVO marketEmailsCustomerVO) {
|
|
|
LambdaQueryWrapper<MarketEmailsEntity> queryWrapper = new LambdaQueryWrapper<>();
|