feat: 06 互动与内容治理落地(评论 / 点赞 / 举报 / 敏感词 / 审核留证)

为什么:
1) 产品侧要先把内容治理闭环跑通才能谈上线:评论可发布、可翻页、可删除,
   违规内容能在后台被审核与驳回,举报要有工单可追溯。本提交把这套补齐。
2) 审核不能只靠人肉:敏感词按 BLOCK/REPLACE/REVIEW 三档处置,
   机审通过即发布(可配置为 PRE_REVIEW 全部先审后发),人审与机审的结论
   都写进 content_audit_record,争议时可回答"当时凭什么放行/驳回"。
3) 举报处理必须与处置打通:结论成立会联动驳回被举报评论,并可选同时封禁被举报用户,
   避免"工单处理完了但违规内容还挂着"。
4) 顺带修复一个真实缺陷:user_favorite / content_like 上有唯一索引,而全局配置会把
   deleteById 改写成逻辑删除,导致取消收藏/点赞后旧的 deleted 行仍占位,
   再次收藏或点赞直接撞唯一索引报错。关系类数据没有留证价值,改为显式物理删除,
   并补了"取消后再来一次"的回归自测。
This commit is contained in:
Vicky committed 2026-10-15 12:03:32 +08:00
1 parent b3179fc836
commit af1dc48494
48 files changed
+1752 -14

No files matched your search

@@ -2,6 +2,17 @@ package com.fruitshorts.playback.dal.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fruitshorts.playback.dal.entity.UserFavorite;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Param;
public interface UserFavoriteMapper extends BaseMapper<UserFavorite> {
/**
* 物理删除收藏关系。
*
* <p>与点赞同理:收藏可反复切换,唯一索引 (user_id, drama_id) 会挡住逻辑删除后的再次收藏。
* 之前用 deleteById(全局配置会改成逻辑删除),取消收藏后再收藏会报唯一键冲突。
*/
@Delete("DELETE FROM user_favorite WHERE user_id = #{userId} AND drama_id = #{dramaId}")
int physicalDelete(@Param("userId") Long userId, @Param("dramaId") Long dramaId);
}
@@ -30,7 +30,8 @@ public class FavoriteService {
.eq(UserFavorite::getDramaId, dramaId)
.last("limit 1"));
if (existing != null) {
favoriteMapper.deleteById(existing.getId());
// 必须物理删除:唯一索引 (user_id, drama_id) 会挡住"取消后再收藏"
favoriteMapper.physicalDelete(userId, dramaId);
return false;
}
UserFavorite favorite = new UserFavorite();
@@ -76,9 +77,7 @@ public class FavoriteService {
@Transactional(rollbackFor = Exception.class)
public void remove(Long userId, Long dramaId) {
favoriteMapper.delete(Wrappers.<UserFavorite>lambdaQuery()
.eq(UserFavorite::getUserId, userId)
.eq(UserFavorite::getDramaId, dramaId));
favoriteMapper.physicalDelete(userId, dramaId);
}
@Transactional(rollbackFor = Exception.class)