Files
backend/internal/service/admin_comment_service.go
lan d3065b30cc feat(admin): add comprehensive admin management system
- Add admin handlers and services for users, posts, comments, groups, and dashboard
- Implement role permission management with ability to view and update permissions
- Add database seeding for roles and Casbin permission policies
- Upgrade Casbin from v2 to v3 with GORM adapter for persistent policy storage
- Add admin-specific repository methods with filtering and pagination
- Register new admin API routes under /api/v1/admin/*
2026-03-14 18:01:55 +08:00

244 lines
7.6 KiB
Go

package service
import (
"context"
"encoding/json"
"carrot_bbs/internal/dto"
"carrot_bbs/internal/model"
"carrot_bbs/internal/repository"
)
// AdminCommentService 管理端评论服务接口
type AdminCommentService interface {
// GetCommentList 获取评论列表(分页、搜索、状态筛选)
GetCommentList(ctx context.Context, page, pageSize int, keyword, postID, authorID, status, startDate, endDate string) ([]dto.AdminCommentListResponse, int64, error)
// GetCommentDetail 获取评论详情
GetCommentDetail(ctx context.Context, commentID string) (*dto.AdminCommentDetailResponse, error)
// DeleteComment 删除评论
DeleteComment(ctx context.Context, commentID string) error
// BatchDeleteComments 批量删除评论
BatchDeleteComments(ctx context.Context, ids []string) (*dto.AdminBatchOperationResponse, error)
// GetCommentsByPostID 获取帖子的评论列表
GetCommentsByPostID(ctx context.Context, postID string, page, pageSize int) ([]dto.AdminCommentListResponse, int64, error)
}
// adminCommentServiceImpl 管理端评论服务实现
type adminCommentServiceImpl struct {
commentRepo *repository.CommentRepository
postRepo *repository.PostRepository
}
// NewAdminCommentService 创建管理端评论服务
func NewAdminCommentService(commentRepo *repository.CommentRepository, postRepo *repository.PostRepository) AdminCommentService {
return &adminCommentServiceImpl{
commentRepo: commentRepo,
postRepo: postRepo,
}
}
// GetCommentList 获取评论列表
func (s *adminCommentServiceImpl) GetCommentList(ctx context.Context, page, pageSize int, keyword, postID, authorID, status, startDate, endDate string) ([]dto.AdminCommentListResponse, int64, error) {
filter := repository.AdminCommentListFilter{
Keyword: keyword,
PostID: postID,
AuthorID: authorID,
Status: status,
StartDate: startDate,
EndDate: endDate,
Page: page,
PageSize: pageSize,
}
comments, total, err := s.commentRepo.GetAdminCommentList(filter)
if err != nil {
return nil, 0, err
}
responses := make([]dto.AdminCommentListResponse, len(comments))
for i, comment := range comments {
responses[i] = s.convertCommentToAdminListResponse(comment)
}
return responses, total, nil
}
// GetCommentDetail 获取评论详情
func (s *adminCommentServiceImpl) GetCommentDetail(ctx context.Context, commentID string) (*dto.AdminCommentDetailResponse, error) {
comment, err := s.commentRepo.GetAdminCommentByID(commentID)
if err != nil {
return nil, err
}
return s.convertCommentToAdminDetailResponse(comment), nil
}
// DeleteComment 删除评论
func (s *adminCommentServiceImpl) DeleteComment(ctx context.Context, commentID string) error {
return s.commentRepo.Delete(commentID)
}
// BatchDeleteComments 批量删除评论
func (s *adminCommentServiceImpl) BatchDeleteComments(ctx context.Context, ids []string) (*dto.AdminBatchOperationResponse, error) {
failedIDs, err := s.commentRepo.BatchDelete(ids)
if err != nil {
return &dto.AdminBatchOperationResponse{
Success: false,
Message: "批量删除失败",
Failed: ids,
}, err
}
if len(failedIDs) == 0 {
return &dto.AdminBatchOperationResponse{
Success: true,
Message: "批量删除成功",
}, nil
}
return &dto.AdminBatchOperationResponse{
Success: true,
Message: "部分评论删除成功",
Failed: failedIDs,
}, nil
}
// GetCommentsByPostID 获取帖子的评论列表
func (s *adminCommentServiceImpl) GetCommentsByPostID(ctx context.Context, postID string, page, pageSize int) ([]dto.AdminCommentListResponse, int64, error) {
comments, total, err := s.commentRepo.GetCommentsByPostIDForAdmin(postID, page, pageSize)
if err != nil {
return nil, 0, err
}
responses := make([]dto.AdminCommentListResponse, len(comments))
for i, comment := range comments {
responses[i] = s.convertCommentToAdminListResponse(comment)
}
return responses, total, nil
}
// convertCommentToAdminListResponse 转换评论为管理端列表响应
func (s *adminCommentServiceImpl) convertCommentToAdminListResponse(comment *model.Comment) dto.AdminCommentListResponse {
// 解析图片
var images []dto.CommentImageResponse
if comment.Images != "" {
var urls []string
if err := json.Unmarshal([]byte(comment.Images), &urls); err == nil {
images = make([]dto.CommentImageResponse, len(urls))
for i, url := range urls {
images[i] = dto.CommentImageResponse{URL: url}
}
}
}
// 作者信息
var author *dto.UserResponse
if comment.User != nil {
author = &dto.UserResponse{
ID: comment.User.ID,
Username: comment.User.Username,
Nickname: comment.User.Nickname,
Email: comment.User.Email,
Phone: comment.User.Phone,
Avatar: comment.User.Avatar,
Bio: comment.User.Bio,
Website: comment.User.Website,
Location: comment.User.Location,
CreatedAt: comment.User.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
}
}
// 帖子简要信息
var postInfo *dto.AdminCommentPostInfo
if comment.PostID != "" {
postInfo = &dto.AdminCommentPostInfo{
ID: comment.PostID,
}
// 尝试获取帖子标题
post, err := s.postRepo.GetByID(comment.PostID)
if err == nil && post != nil {
postInfo.Title = post.Title
}
}
return dto.AdminCommentListResponse{
ID: comment.ID,
PostID: comment.PostID,
UserID: comment.UserID,
ParentID: comment.ParentID,
RootID: comment.RootID,
Content: comment.Content,
Images: images,
Status: string(comment.Status),
LikesCount: comment.LikesCount,
RepliesCount: comment.RepliesCount,
CreatedAt: comment.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
UpdatedAt: comment.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"),
Author: author,
Post: postInfo,
}
}
// convertCommentToAdminDetailResponse 转换评论为管理端详情响应
func (s *adminCommentServiceImpl) convertCommentToAdminDetailResponse(comment *model.Comment) *dto.AdminCommentDetailResponse {
// 解析图片
var images []dto.CommentImageResponse
if comment.Images != "" {
var urls []string
if err := json.Unmarshal([]byte(comment.Images), &urls); err == nil {
images = make([]dto.CommentImageResponse, len(urls))
for i, url := range urls {
images[i] = dto.CommentImageResponse{URL: url}
}
}
}
// 作者信息
var author *dto.UserResponse
if comment.User != nil {
author = &dto.UserResponse{
ID: comment.User.ID,
Username: comment.User.Username,
Nickname: comment.User.Nickname,
Email: comment.User.Email,
Phone: comment.User.Phone,
Avatar: comment.User.Avatar,
Bio: comment.User.Bio,
Website: comment.User.Website,
Location: comment.User.Location,
CreatedAt: comment.User.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
}
}
// 帖子简要信息
var postInfo *dto.AdminCommentPostInfo
if comment.PostID != "" {
postInfo = &dto.AdminCommentPostInfo{
ID: comment.PostID,
}
// 尝试获取帖子标题
post, err := s.postRepo.GetByID(comment.PostID)
if err == nil && post != nil {
postInfo.Title = post.Title
}
}
return &dto.AdminCommentDetailResponse{
ID: comment.ID,
PostID: comment.PostID,
UserID: comment.UserID,
ParentID: comment.ParentID,
RootID: comment.RootID,
Content: comment.Content,
Images: images,
Status: string(comment.Status),
LikesCount: comment.LikesCount,
RepliesCount: comment.RepliesCount,
CreatedAt: comment.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
UpdatedAt: comment.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"),
Author: author,
Post: postInfo,
}
}