Browse Source

chore: auto bump version and changelog [skip ci]

iwt 2 months ago
parent
commit
42917d8cd8

+ 29 - 4
cfc-backend/src/main/java/com/etotem/cfc/service/ArticleService.java

@@ -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

+ 1 - 1
cfc-web/.last_build_commit

@@ -1 +1 @@
-0a66391a1e09cb68f403bfdf8ee45cacc4ab2b34
+8224f26cf77406f1290746472a35e962d2adb277

+ 2 - 2
cfc-web/package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "cfc-web",
-  "version": "1.0.1288",
+  "version": "1.0.1289",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "cfc-web",
-      "version": "1.0.1288",
+      "version": "1.0.1289",
       "dependencies": {
         "@wangeditor/editor": "^5.1.23",
         "@wangeditor/editor-for-vue": "^1.0.2",

+ 11 - 6
cfc-web/src/views/admin/ArticleManage.vue

@@ -116,6 +116,11 @@
             <span class="sort-header" @click.stop="onSortClick('viewCount', $event)" @dblclick.stop="onSortToggle('viewCount')">阅读<span v-if="sortIndex('viewCount') !== null" class="sort-index" :class="sortClass('viewCount') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('viewCount') }}</span>{{ sortIcon('viewCount') }}</span>
           </template>
         </el-table-column>
+        <el-table-column label="总阅读时长" width="110">
+          <template slot-scope="{ row }">
+            {{ formatDuration(row.totalDurationSeconds) }}
+          </template>
+        </el-table-column>
 
         <el-table-column label="发布时间" width="160">
           <template slot-scope="{ row }">
@@ -240,19 +245,19 @@
             {{ row.nickname || '-' }}
           </template>
         </el-table-column>
-        <el-table-column prop="duration_seconds" label="累计时长" width="120">
+        <el-table-column prop="total_duration_seconds" label="累计时长" width="110">
           <template slot-scope="{ row }">
-            {{ formatDuration(row.duration_seconds) }}
+            {{ formatDuration(row.total_duration_seconds) }}
           </template>
         </el-table-column>
-        <el-table-column prop="read_date" label="最后阅读日期" width="130">
+        <el-table-column prop="read_count" label="阅读次数" width="90">
           <template slot-scope="{ row }">
-            {{ row.read_date || '-' }}
+            {{ row.read_count || 0 }}次
           </template>
         </el-table-column>
-        <el-table-column prop="read_at" label="最后阅读时间" width="170">
+        <el-table-column prop="last_read_at" label="最后阅读时间" width="170">
           <template slot-scope="{ row }">
-            {{ formatTime(row.read_at) }}
+            {{ formatTime(row.last_read_at) }}
           </template>
         </el-table-column>
       </el-table>