Просмотр исходного кода

feat(backend): 文章评论审核功能——AdminArticleController/ArticleCommentController/ArticleCommentService

Xiaogang Liao 3 месяцев назад
Родитель
Сommit
212f95a94a

+ 13 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminArticleController.java

@@ -4,6 +4,7 @@ import com.etotem.cfc.common.Result;
 import com.etotem.cfc.entity.Article;
 import com.etotem.cfc.entity.Article;
 import com.etotem.cfc.entity.ArticleCategory;
 import com.etotem.cfc.entity.ArticleCategory;
 import com.etotem.cfc.service.ArticleCategoryService;
 import com.etotem.cfc.service.ArticleCategoryService;
+import com.etotem.cfc.service.ArticleCommentService;
 import com.etotem.cfc.service.ArticleService;
 import com.etotem.cfc.service.ArticleService;
 import com.etotem.cfc.service.FileStorageService;
 import com.etotem.cfc.service.FileStorageService;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -27,6 +28,9 @@ public class AdminArticleController {
     @Resource
     @Resource
     private FileStorageService fileStorageService;
     private FileStorageService fileStorageService;
 
 
+    @Resource
+    private ArticleCommentService articleCommentService;
+
     @PostMapping("/list")
     @PostMapping("/list")
     public Result<Page<Article>> list(@RequestBody Map<String, Object> body) {
     public Result<Page<Article>> list(@RequestBody Map<String, Object> body) {
         String status = (String) body.get("status");
         String status = (String) body.get("status");
@@ -260,6 +264,15 @@ public class AdminArticleController {
         }
         }
     }
     }
 
 
+    @PostMapping("/comments/list")
+    public Result<Page<Map<String, Object>>> commentList(@RequestBody Map<String, Object> body) {
+        Long articleId = body.get("articleId") != null ? Long.valueOf(body.get("articleId").toString()) : null;
+        String status = (String) body.get("status");
+        int page = body.get("page") != null ? Integer.parseInt(body.get("page").toString()) : 1;
+        int size = body.get("size") != null ? Integer.parseInt(body.get("size").toString()) : 20;
+        return Result.success(articleCommentService.getAdminCommentList(articleId, status, page, size));
+    }
+
     @PostMapping("/categories/list")
     @PostMapping("/categories/list")
     public Result<List<ArticleCategory>> categoryList() {
     public Result<List<ArticleCategory>> categoryList() {
         return Result.success(articleCategoryService.listAll());
         return Result.success(articleCategoryService.listAll());

+ 10 - 3
cfc-backend/src/main/java/com/etotem/cfc/controller/content/ArticleCommentController.java

@@ -45,7 +45,12 @@ public class ArticleCommentController {
     }
     }
 
 
     @PostMapping("/comments/audit")
     @PostMapping("/comments/audit")
-    public Result<String> auditComment(@RequestBody Map<String, Object> params, @RequestAttribute("userId") Long userId) {
+    public Result<String> auditComment(@RequestBody Map<String, Object> params,
+                                        @RequestAttribute("userId") Long userId,
+                                        @RequestAttribute("role") String role) {
+        if (!"admin".equals(role) && !"teacher".equals(role)) {
+            return Result.error("无权限,仅管理员或成长规划师可审核评论");
+        }
         Long commentId = Long.valueOf(params.get("commentId").toString());
         Long commentId = Long.valueOf(params.get("commentId").toString());
         String status = (String) params.get("status");
         String status = (String) params.get("status");
         if (!"approved".equals(status) && !"rejected".equals(status)) return Result.error("status必须为approved或rejected");
         if (!"approved".equals(status) && !"rejected".equals(status)) return Result.error("status必须为approved或rejected");
@@ -53,9 +58,11 @@ public class ArticleCommentController {
     }
     }
 
 
     @PostMapping("/comments/pending")
     @PostMapping("/comments/pending")
-    public Result<List<ArticleComment>> getPendingComments(@RequestBody Map<String, Object> params) {
+    public Result<List<Map<String, Object>>> getPendingComments(@RequestBody Map<String, Object> params,
+                                                                  @RequestAttribute("userId") Long userId,
+                                                                  @RequestAttribute("role") String role) {
         Long articleId = params.get("articleId") != null ? Long.valueOf(params.get("articleId").toString()) : null;
         Long articleId = params.get("articleId") != null ? Long.valueOf(params.get("articleId").toString()) : null;
-        return Result.success(articleCommentService.getPendingComments(articleId));
+        return Result.success(articleCommentService.getPendingCommentsWithDetail(articleId, userId, role));
     }
     }
 
 
     @PostMapping("/comments/my")
     @PostMapping("/comments/my")

+ 114 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/ArticleCommentService.java

@@ -1,6 +1,8 @@
 package com.etotem.cfc.service;
 package com.etotem.cfc.service;
 
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.etotem.cfc.entity.Article;
 import com.etotem.cfc.entity.ArticleComment;
 import com.etotem.cfc.entity.ArticleComment;
 import com.etotem.cfc.entity.User;
 import com.etotem.cfc.entity.User;
 import com.etotem.cfc.mapper.ArticleCommentMapper;
 import com.etotem.cfc.mapper.ArticleCommentMapper;
@@ -11,6 +13,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
 import java.util.*;
 import java.util.*;
+import java.util.stream.Collectors;
 
 
 @Service
 @Service
 public class ArticleCommentService {
 public class ArticleCommentService {
@@ -151,6 +154,117 @@ public class ArticleCommentService {
         return articleCommentMapper.selectList(wrapper);
         return articleCommentMapper.selectList(wrapper);
     }
     }
 
 
+    public List<Map<String, Object>> getPendingCommentsWithDetail(Long articleId, Long userId, String role) {
+        LambdaQueryWrapper<ArticleComment> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(ArticleComment::getStatus, "pending");
+
+        if (articleId != null) {
+            wrapper.eq(ArticleComment::getArticleId, articleId);
+        }
+
+        // 非管理员则只看自己文章的评论
+        if (!"admin".equals(role) && userId != null) {
+            List<Article> myArticles = articleMapper.selectList(
+                    new LambdaQueryWrapper<Article>().eq(Article::getCreatedBy, userId)
+            );
+            if (myArticles.isEmpty()) return new ArrayList<>();
+            Set<Long> articleIds = myArticles.stream().map(Article::getId).collect(Collectors.toSet());
+            wrapper.in(ArticleComment::getArticleId, articleIds);
+        }
+
+        wrapper.orderByDesc(ArticleComment::getCreatedAt);
+        List<ArticleComment> comments = articleCommentMapper.selectList(wrapper);
+
+        Map<Long, User> userCache = new HashMap<>();
+        Map<Long, Article> articleCache = new HashMap<>();
+        List<Map<String, Object>> result = new ArrayList<>();
+
+        for (ArticleComment c : comments) {
+            Map<String, Object> item = new HashMap<>();
+            item.put("id", c.getId());
+            item.put("articleId", c.getArticleId());
+            item.put("parentId", c.getParentId());
+            item.put("replyToId", c.getReplyToId());
+            item.put("content", c.getContent());
+            item.put("status", c.getStatus());
+            item.put("createdAt", c.getCreatedAt());
+            item.put("auditBy", c.getAuditBy());
+            item.put("auditAt", c.getAuditAt());
+
+            User user = getUserCached(c.getUserId(), userCache);
+            if (user != null) {
+                item.put("userName", user.getNickname() != null ? user.getNickname() : user.getPhone());
+                item.put("userAvatar", user.getAvatar());
+            }
+
+            Article article = getArticleCached(c.getArticleId(), articleCache);
+            if (article != null) {
+                item.put("articleTitle", article.getTitle());
+                item.put("articleAuthorId", article.getCreatedBy());
+            }
+
+            result.add(item);
+        }
+        return result;
+    }
+
+    /**
+     * 管理员获取评论列表(分页,按状态筛选,含用户和文章信息)
+     */
+    public Page<Map<String, Object>> getAdminCommentList(Long articleId, String status, int page, int size) {
+        LambdaQueryWrapper<ArticleComment> wrapper = new LambdaQueryWrapper<>();
+        if (articleId != null) {
+            wrapper.eq(ArticleComment::getArticleId, articleId);
+        }
+        if (status != null && !status.isEmpty()) {
+            wrapper.eq(ArticleComment::getStatus, status);
+        }
+        wrapper.orderByDesc(ArticleComment::getCreatedAt);
+
+        Page<ArticleComment> p = articleCommentMapper.selectPage(new Page<>(page, size), wrapper);
+        Page<Map<String, Object>> result = new Page<>(p.getCurrent(), p.getSize(), p.getTotal());
+
+        Map<Long, User> userCache = new HashMap<>();
+        Map<Long, Article> articleCache = new HashMap<>();
+        List<Map<String, Object>> records = new ArrayList<>();
+
+        for (ArticleComment c : p.getRecords()) {
+            Map<String, Object> item = new HashMap<>();
+            item.put("id", c.getId());
+            item.put("articleId", c.getArticleId());
+            item.put("parentId", c.getParentId());
+            item.put("replyToId", c.getReplyToId());
+            item.put("content", c.getContent());
+            item.put("status", c.getStatus());
+            item.put("createdAt", c.getCreatedAt());
+            item.put("auditBy", c.getAuditBy());
+            item.put("auditAt", c.getAuditAt());
+
+            User user = getUserCached(c.getUserId(), userCache);
+            if (user != null) {
+                item.put("userName", user.getNickname() != null ? user.getNickname() : user.getPhone());
+                item.put("userAvatar", user.getAvatar());
+            }
+
+            Article article = getArticleCached(c.getArticleId(), articleCache);
+            if (article != null) {
+                item.put("articleTitle", article.getTitle());
+            }
+
+            records.add(item);
+        }
+        result.setRecords(records);
+        return result;
+    }
+
+    private Article getArticleCached(Long articleId, Map<Long, Article> cache) {
+        if (articleId == null) return null;
+        if (!cache.containsKey(articleId)) {
+            cache.put(articleId, articleMapper.selectById(articleId));
+        }
+        return cache.get(articleId);
+    }
+
     /**
     /**
      * 获取用户的评论
      * 获取用户的评论
      */
      */