From 742107f9449ec447bf93135eedf9b2346089dd88 Mon Sep 17 00:00:00 2001 From: ziin Date: Fri, 20 Mar 2026 15:26:46 +0800 Subject: [PATCH] Add comment reporting API and service --- .../AiCompanionCommentController.java | 13 ++++ .../mapper/KeyboardAiCommentReportMapper.java | 11 +++ .../model/dto/comment/CommentReportReq.java | 30 +++++++ .../model/entity/KeyboardAiCommentReport.java | 68 ++++++++++++++++ .../KeyboardAiCommentReportService.java | 21 +++++ .../KeyboardAiCommentReportServiceImpl.java | 78 +++++++++++++++++++ .../mapper/KeyboardAiCommentReportMapper.xml | 21 +++++ 7 files changed, 242 insertions(+) create mode 100644 src/main/java/com/yolo/keyborad/mapper/KeyboardAiCommentReportMapper.java create mode 100644 src/main/java/com/yolo/keyborad/model/dto/comment/CommentReportReq.java create mode 100644 src/main/java/com/yolo/keyborad/model/entity/KeyboardAiCommentReport.java create mode 100644 src/main/java/com/yolo/keyborad/service/KeyboardAiCommentReportService.java create mode 100644 src/main/java/com/yolo/keyborad/service/impl/KeyboardAiCommentReportServiceImpl.java create mode 100644 src/main/resources/mapper/KeyboardAiCommentReportMapper.xml diff --git a/src/main/java/com/yolo/keyborad/controller/AiCompanionCommentController.java b/src/main/java/com/yolo/keyborad/controller/AiCompanionCommentController.java index 5b7aae2..bb7eb28 100644 --- a/src/main/java/com/yolo/keyborad/controller/AiCompanionCommentController.java +++ b/src/main/java/com/yolo/keyborad/controller/AiCompanionCommentController.java @@ -10,7 +10,9 @@ import com.yolo.keyborad.exception.BusinessException; import com.yolo.keyborad.model.dto.comment.CommentAddReq; import com.yolo.keyborad.model.dto.comment.CommentLikeReq; import com.yolo.keyborad.model.dto.comment.CommentPageReq; +import com.yolo.keyborad.model.dto.comment.CommentReportReq; import com.yolo.keyborad.model.vo.CommentVO; +import com.yolo.keyborad.service.KeyboardAiCommentReportService; import com.yolo.keyborad.service.KeyboardAiCompanionCommentService; import com.yolo.keyborad.service.KeyboardAiCompanionCommentLikeService; import io.swagger.v3.oas.annotations.Operation; @@ -35,6 +37,9 @@ public class AiCompanionCommentController { @Resource private KeyboardAiCompanionCommentLikeService commentLikeService; + @Resource + private KeyboardAiCommentReportService commentReportService; + @PostMapping("/add") @Operation(summary = "发表评论", description = "用户对AI陪聊角色发表评论") public BaseResponse addComment(@RequestBody CommentAddReq req) { @@ -75,4 +80,12 @@ public class AiCompanionCommentController { boolean result = commentLikeService.toggleLike(userId, req.getCommentId()); return ResultUtils.success(result); } + + @PostMapping("/report") + @Operation(summary = "举报评论", description = "举报AI陪聊角色评论,支持多种举报类型(可多选):1=色情低俗, 2=政治敏感, 3=暴力恐怖, 4=侵权/冒充, 5=价值观问题, 99=其他") + public BaseResponse reportComment(@RequestBody CommentReportReq req) { + Long userId = StpUtil.getLoginIdAsLong(); + Long reportId = commentReportService.reportComment(userId, req); + return ResultUtils.success(reportId); + } } diff --git a/src/main/java/com/yolo/keyborad/mapper/KeyboardAiCommentReportMapper.java b/src/main/java/com/yolo/keyborad/mapper/KeyboardAiCommentReportMapper.java new file mode 100644 index 0000000..3982912 --- /dev/null +++ b/src/main/java/com/yolo/keyborad/mapper/KeyboardAiCommentReportMapper.java @@ -0,0 +1,11 @@ +package com.yolo.keyborad.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yolo.keyborad.model.entity.KeyboardAiCommentReport; + +/* + * @author: ziin + * @date: 2026/3/20 + */ +public interface KeyboardAiCommentReportMapper extends BaseMapper { +} diff --git a/src/main/java/com/yolo/keyborad/model/dto/comment/CommentReportReq.java b/src/main/java/com/yolo/keyborad/model/dto/comment/CommentReportReq.java new file mode 100644 index 0000000..75bf4a2 --- /dev/null +++ b/src/main/java/com/yolo/keyborad/model/dto/comment/CommentReportReq.java @@ -0,0 +1,30 @@ +package com.yolo.keyborad.model.dto.comment; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/* + * @author: ziin + * @date: 2026/3/20 + */ +@Data +@Schema(description = "评论举报请求") +public class CommentReportReq { + + @Schema(description = "评论ID", requiredMode = Schema.RequiredMode.REQUIRED) + private Long commentId; + + @Schema(description = "举报类型列表:1=色情低俗, 2=政治敏感, 3=暴力恐怖, 4=侵权/冒充, 5=价值观问题, 99=其他,支持多选", requiredMode = Schema.RequiredMode.REQUIRED) + private List reportTypes; + + @Schema(description = "详细描述") + private String reportDesc; + + @Schema(description = "评论上下文快照JSON") + private String chatContext; + + @Schema(description = "图片证据URL") + private String evidenceImageUrl; +} diff --git a/src/main/java/com/yolo/keyborad/model/entity/KeyboardAiCommentReport.java b/src/main/java/com/yolo/keyborad/model/entity/KeyboardAiCommentReport.java new file mode 100644 index 0000000..7d7a767 --- /dev/null +++ b/src/main/java/com/yolo/keyborad/model/entity/KeyboardAiCommentReport.java @@ -0,0 +1,68 @@ +package com.yolo.keyborad.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + +/* + * @author: ziin + * @date: 2026/3/20 + */ + +/** + * AI评论举报记录表 + */ +@Data +@Schema(description = "AI评论举报记录表") +@TableName(value = "keyboard_ai_comment_report") +public class KeyboardAiCommentReport { + + @TableId(value = "id", type = IdType.AUTO) + @Schema(description = "举报记录唯一ID") + private Long id; + + @TableField(value = "comment_id") + @Schema(description = "被举报的评论ID") + private Long commentId; + + @TableField(value = "user_id") + @Schema(description = "发起举报的用户ID") + private Long userId; + + @TableField(value = "report_type") + @Schema(description = "举报类型,多选时逗号分隔") + private String reportType; + + @TableField(value = "report_desc") + @Schema(description = "用户填写的详细举报描述") + private String reportDesc; + + @TableField(value = "chat_context") + @Schema(description = "评论上下文快照JSON") + private String chatContext; + + @TableField(value = "evidence_image_url") + @Schema(description = "图片证据URL") + private String evidenceImageUrl; + + @TableField(value = "\"status\"") + @Schema(description = "处理状态:0=待处理, 1=违规确立, 2=无效举报, 3=已忽略") + private Short status; + + @TableField(value = "admin_remark") + @Schema(description = "管理员处理备注") + private String adminRemark; + + @TableField(value = "created_at") + @Schema(description = "举报提交时间") + private Date createdAt; + + @TableField(value = "updated_at") + @Schema(description = "最后更新时间") + private Date updatedAt; +} diff --git a/src/main/java/com/yolo/keyborad/service/KeyboardAiCommentReportService.java b/src/main/java/com/yolo/keyborad/service/KeyboardAiCommentReportService.java new file mode 100644 index 0000000..933ddd8 --- /dev/null +++ b/src/main/java/com/yolo/keyborad/service/KeyboardAiCommentReportService.java @@ -0,0 +1,21 @@ +package com.yolo.keyborad.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.yolo.keyborad.model.dto.comment.CommentReportReq; +import com.yolo.keyborad.model.entity.KeyboardAiCommentReport; + +/* + * @author: ziin + * @date: 2026/3/20 + */ +public interface KeyboardAiCommentReportService extends IService { + + /** + * 举报评论 + * + * @param userId 用户ID + * @param req 举报请求 + * @return 举报记录ID + */ + Long reportComment(Long userId, CommentReportReq req); +} diff --git a/src/main/java/com/yolo/keyborad/service/impl/KeyboardAiCommentReportServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/KeyboardAiCommentReportServiceImpl.java new file mode 100644 index 0000000..a5eb51b --- /dev/null +++ b/src/main/java/com/yolo/keyborad/service/impl/KeyboardAiCommentReportServiceImpl.java @@ -0,0 +1,78 @@ +package com.yolo.keyborad.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.yolo.keyborad.common.ErrorCode; +import com.yolo.keyborad.exception.BusinessException; +import com.yolo.keyborad.mapper.KeyboardAiCommentReportMapper; +import com.yolo.keyborad.model.dto.comment.CommentReportReq; +import com.yolo.keyborad.model.entity.KeyboardAiCommentReport; +import com.yolo.keyborad.model.entity.KeyboardAiCompanionComment; +import com.yolo.keyborad.service.KeyboardAiCommentReportService; +import com.yolo.keyborad.service.KeyboardAiCompanionCommentService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.Set; +import java.util.stream.Collectors; + +/* + * @author: ziin + * @date: 2026/3/20 + */ +@Service +public class KeyboardAiCommentReportServiceImpl extends ServiceImpl + implements KeyboardAiCommentReportService { + + private static final short PENDING_STATUS = 0; + + private static final Set VALID_REPORT_TYPES = Set.of( + (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 99 + ); + + @Resource + private KeyboardAiCompanionCommentService commentService; + + @Override + public Long reportComment(Long userId, CommentReportReq req) { + validateRequest(req); + + KeyboardAiCompanionComment comment = commentService.getById(req.getCommentId()); + if (comment == null) { + throw new BusinessException(ErrorCode.COMMENT_NOT_FOUND); + } + + KeyboardAiCommentReport report = buildReport(userId, req); + boolean saved = this.save(report); + if (!saved) { + throw new BusinessException(ErrorCode.OPERATION_ERROR); + } + return report.getId(); + } + + private void validateRequest(CommentReportReq req) { + if (req.getCommentId() == null) { + throw new BusinessException(ErrorCode.COMMENT_ID_EMPTY); + } + if (req.getReportTypes() == null || req.getReportTypes().isEmpty()) { + throw new BusinessException(ErrorCode.REPORT_TYPE_EMPTY); + } + boolean hasInvalidType = req.getReportTypes().stream().anyMatch(type -> !VALID_REPORT_TYPES.contains(type)); + if (hasInvalidType) { + throw new BusinessException(ErrorCode.REPORT_TYPE_INVALID); + } + } + + private KeyboardAiCommentReport buildReport(Long userId, CommentReportReq req) { + KeyboardAiCommentReport report = new KeyboardAiCommentReport(); + report.setUserId(userId); + report.setCommentId(req.getCommentId()); + report.setReportType(req.getReportTypes().stream().map(String::valueOf).collect(Collectors.joining(","))); + report.setReportDesc(req.getReportDesc()); + report.setChatContext(req.getChatContext()); + report.setEvidenceImageUrl(req.getEvidenceImageUrl()); + report.setStatus(PENDING_STATUS); + report.setCreatedAt(new Date()); + return report; + } +} diff --git a/src/main/resources/mapper/KeyboardAiCommentReportMapper.xml b/src/main/resources/mapper/KeyboardAiCommentReportMapper.xml new file mode 100644 index 0000000..aa25a3e --- /dev/null +++ b/src/main/resources/mapper/KeyboardAiCommentReportMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + id, comment_id, user_id, report_type, report_desc, chat_context, evidence_image_url, + "status", admin_remark, created_at, updated_at + +