feat: 合规红线(提交审核接入敏感词检查 + 内容审核抽象 + 合规声明)

This commit is contained in:
Zhou Weidong committed 2026-10-17 03:03:51 +08:00
1 parent 9d92fa2a73
commit abea0a6c39
5 files changed
+112

No files matched your search

+5
View File
@@ -39,5 +39,10 @@
<groupId>com.fruitshorts</groupId>
<artifactId>fruitshorts-module-system</artifactId>
</dependency>
<!-- 提交审核前做敏感词自动检查(词库在互动域),拦截违规标题/描述 -->
<dependency>
<groupId>com.fruitshorts</groupId>
<artifactId>fruitshorts-module-interaction</artifactId>
</dependency>
</dependencies>
</project>
@@ -12,6 +12,9 @@ import com.fruitshorts.content.dal.entity.Drama;
import com.fruitshorts.content.enums.ContentStatus;
import com.fruitshorts.content.service.DramaService;
import com.fruitshorts.content.service.EpisodeService;
import com.fruitshorts.content.vo.EpisodeRespVO;
import com.fruitshorts.interaction.service.SensitiveWordCheck;
import com.fruitshorts.interaction.service.SensitiveWordService;
import com.fruitshorts.creator.dal.entity.ContentSubmission;
import com.fruitshorts.creator.dal.entity.Creator;
import com.fruitshorts.creator.dal.mapper.ContentSubmissionMapper;
@@ -52,6 +55,7 @@ public class ContentSubmissionService {
private final ContentSubmissionMapper submissionMapper;
private final DramaService dramaService;
private final EpisodeService episodeService;
private final SensitiveWordService sensitiveWordService;
public PageResult<ContentSubmission> page(SubmissionQueryReqVO req) {
Page<ContentSubmission> page = new Page<>(req.getSafePageIndex(), req.getSafePageSize());
@@ -90,6 +94,7 @@ public class ContentSubmissionService {
if (!Objects.equals(drama.getCreatorId(), creator.getId())) {
throw new ServiceException(ErrorCode.FORBIDDEN, "无权访问该作品");
}
checkContentSensitive(drama);
if (!Set.of(TYPE_CREATE, TYPE_UPDATE, TYPE_PUBLISH, TYPE_OFFLINE).contains(type)) {
throw new ServiceException(ErrorCode.BAD_REQUEST, "未知的提交类型: " + type);
}
@@ -166,6 +171,30 @@ public class ContentSubmissionService {
return submission;
}
/**
* 提交审核前的敏感词自动检查:命中禁止词(BLOCK)直接拦截,命中待审词(REVIEW)仍放行交由人工复核。
* 覆盖标题、副标题、简介、标签与全部分集标题。
*/
private void checkContentSensitive(Drama drama) {
checkText(drama.getTitle(), "标题");
checkText(drama.getSubtitle(), "副标题");
checkText(drama.getSynopsis(), "简介");
checkText(drama.getTags(), "标签");
for (EpisodeRespVO ep : episodeService.listByDrama(drama.getId(), null)) {
checkText(ep.getTitle(), "分集标题");
}
}
private void checkText(String text, String field) {
if (!StringUtils.hasText(text)) {
return;
}
SensitiveWordCheck check = sensitiveWordService.check(text);
if (check.blocked()) {
throw new ServiceException(ErrorCode.OPERATION_NOT_ALLOWED, field + check.reason());
}
}
/**
* 创作者撤回自己的提交(撤回重提)。
* 只有还没出结果的提交能撤回;撤回后短剧退回草稿,创作者可以继续改。