|
|
@@ -29,6 +29,7 @@ import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
import javax.annotation.Resource;
|
|
|
import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
import com.etotem.cfc.util.SortUtil;
|
|
|
|
|
|
@Slf4j
|
|
|
@@ -355,10 +356,10 @@ public class ArticleService {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 按文章 ID 分页查询阅读记录,返回用户昵称、时长、最后阅读时间
|
|
|
+ * 按文章 ID 分页查询阅读记录(每人聚合一行),返回昵称、累计时长、阅读次数、最后阅读时间
|
|
|
*/
|
|
|
public Page<Map<String, Object>> getArticleReadingRecords(Long articleId, int page, int size) {
|
|
|
- long total = articleReadingRecordMapper.countByArticle(articleId);
|
|
|
+ long total = articleReadingRecordMapper.countDistinctByArticle(articleId);
|
|
|
if (total == 0) {
|
|
|
Page<Map<String, Object>> empty = new Page<>(page, size);
|
|
|
empty.setTotal(0);
|
|
|
@@ -366,7 +367,7 @@ public class ArticleService {
|
|
|
return empty;
|
|
|
}
|
|
|
int offset = (page - 1) * size;
|
|
|
- List<Map<String, Object>> records = articleReadingRecordMapper.selectByArticle(articleId, offset, size);
|
|
|
+ List<Map<String, Object>> records = articleReadingRecordMapper.selectByArticleAggregated(articleId, offset, size);
|
|
|
Page<Map<String, Object>> result = new Page<>(page, size);
|
|
|
result.setTotal(total);
|
|
|
result.setRecords(records);
|
|
|
@@ -414,7 +415,31 @@ public class ArticleService {
|
|
|
}
|
|
|
SortUtil.applySort(wrapper, sortSpecs, null);
|
|
|
|
|
|
- return articleMapper.selectPage(new Page<>(page, size), wrapper);
|
|
|
+ Page<Article> pageResult = articleMapper.selectPage(new Page<>(page, size), wrapper);
|
|
|
+
|
|
|
+ // 批量填充每篇文章的总阅读时长(按 child 聚合去重后求和)
|
|
|
+ List<Article> records = pageResult.getRecords();
|
|
|
+ if (records != null && !records.isEmpty()) {
|
|
|
+ String ids = records.stream()
|
|
|
+ .map(a -> String.valueOf(a.getId()))
|
|
|
+ .collect(Collectors.joining(","));
|
|
|
+ List<Map<String, Object>> durationRows = jdbcTemplate.queryForList(
|
|
|
+ "SELECT article_id, SUM(duration_seconds) AS total_duration " +
|
|
|
+ "FROM article_reading_records WHERE article_id IN (" + ids + ") GROUP BY article_id");
|
|
|
+ Map<Long, Integer> durationMap = new HashMap<>();
|
|
|
+ for (Map<String, Object> row : durationRows) {
|
|
|
+ Number articleId = (Number) row.get("article_id");
|
|
|
+ Number total = (Number) row.get("total_duration");
|
|
|
+ if (articleId != null && total != null) {
|
|
|
+ durationMap.put(articleId.longValue(), total.intValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (Article article : records) {
|
|
|
+ article.setTotalDurationSeconds(durationMap.getOrDefault(article.getId(), 0));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return pageResult;
|
|
|
}
|
|
|
|
|
|
@Transactional
|