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:
1 parent
b3179fc836
commit
af1dc48494
48 files changed
+1752
-14
No files matched your search
+11
@@ -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);
|
||||
}
|
||||
+3
-4
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user