|
|
@ -1,6 +1,7 @@ |
|
|
package com.youlai.boot.admin.service.impl; |
|
|
package com.youlai.boot.admin.service.impl; |
|
|
|
|
|
|
|
|
import com.alibaba.fastjson.JSON; |
|
|
import com.alibaba.fastjson.JSON; |
|
|
|
|
|
import com.alibaba.fastjson.JSONArray; |
|
|
import com.alibaba.fastjson.JSONObject; |
|
|
import com.alibaba.fastjson.JSONObject; |
|
|
import com.aliyun.green20220302.models.*; |
|
|
import com.aliyun.green20220302.models.*; |
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|
|
@ -38,14 +39,14 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
/** |
|
|
/** |
|
|
* 执行内容审核(供业务层在内容创建/修改后调用)。 |
|
|
* 执行内容审核(供业务层在内容创建/修改后调用)。 |
|
|
* |
|
|
* |
|
|
* @param moduleCode 业务模块编码,对应 mini_content_audit_config.module_code |
|
|
* @param moduleCode 业务模块编码 |
|
|
* @param bizId 业务数据ID(日记ID / 评论ID 等) |
|
|
* @param bizId 业务数据ID |
|
|
* @param content 待审核内容 {texts, images, videos} |
|
|
* @param content 待审核内容 {texts, images, videos} |
|
|
* @return {status, auditId};配置关闭或无配置时返回 null,调用方以此判断是否跳过审核 |
|
|
* @return {status, auditId};配置关闭或无配置时返回 null |
|
|
*/ |
|
|
*/ |
|
|
@Override |
|
|
@Override |
|
|
public Map<String, Object> executeAudit(String moduleCode, Long bizId, AuditContentDTO content, String triggerType) { |
|
|
public Map<String, Object> executeAudit(String moduleCode, Long bizId, AuditContentDTO content, String triggerType) { |
|
|
// 1) 查询对应模块的审核配置
|
|
|
// 1) 查询审核配置
|
|
|
MiniContentAuditConfig config = findAuditConfig(moduleCode); |
|
|
MiniContentAuditConfig config = findAuditConfig(moduleCode); |
|
|
if (config == null || isAuditDisabled(config)) { |
|
|
if (config == null || isAuditDisabled(config)) { |
|
|
return null; |
|
|
return null; |
|
|
@ -53,163 +54,45 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
|
|
|
|
|
|
String auditType = config.getAuditType(); |
|
|
String auditType = config.getAuditType(); |
|
|
|
|
|
|
|
|
// 2) 创建审核汇总记录
|
|
|
// 2) 创建审核汇总
|
|
|
MiniContentAudit audit = contentAuditService.createAudit(moduleCode, bizId, auditType, triggerType); |
|
|
MiniContentAudit audit = contentAuditService.createAudit(moduleCode, bizId, auditType, triggerType); |
|
|
Long auditId = audit.getId(); |
|
|
Long auditId = audit.getId(); |
|
|
|
|
|
|
|
|
// 3) 拆解待审核内容,批量创建审核任务明细
|
|
|
// 3) 拆解内容,批量创建审核任务
|
|
|
contentAuditTaskService.batchCreateTasks(auditId, auditType, |
|
|
contentAuditTaskService.batchCreateTasks(auditId, auditType, |
|
|
content.getTexts(), content.getImages(), content.getVideos()); |
|
|
content.getTexts(), content.getImages(), content.getVideos()); |
|
|
|
|
|
|
|
|
// 4) 根据审核类型执行不同策略
|
|
|
// 4) 按审核类型执行
|
|
|
if (AuditConstants.AUDIT_TYPE_MANUAL.equals(auditType)) { |
|
|
if (AuditConstants.AUDIT_TYPE_MANUAL.equals(auditType)) { |
|
|
|
|
|
// 人工审核
|
|
|
return executeManualAudit(auditId); |
|
|
return executeManualAudit(auditId); |
|
|
} |
|
|
} |
|
|
if (AuditConstants.AUDIT_TYPE_MIXED.equals(auditType)) { |
|
|
|
|
|
return executeMixedAudit(auditId); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// machine(默认):调 AI 并按策略裁决
|
|
|
// machine:调 AI 并按策略裁决
|
|
|
String strictness = config.getRiskStrategy() != null ? config.getRiskStrategy() : AuditConstants.STRATEGY_NORMAL; |
|
|
String strictness = config.getRiskStrategy() != null ? config.getRiskStrategy() : AuditConstants.STRATEGY_NORMAL; |
|
|
List<MiniContentAuditTask> tasks = contentAuditTaskService.listTasksByAuditId(auditId); |
|
|
List<MiniContentAuditTask> tasks = contentAuditTaskService.listTasksByAuditId(auditId); |
|
|
executeBatchAuditByType(tasks, strictness); |
|
|
executeBatchAuditByType(tasks, strictness); // 进入机器审核
|
|
|
List<MiniContentAuditTask> updatedTasks = contentAuditTaskService.listTasksByAuditId(auditId); |
|
|
List<MiniContentAuditTask> updatedTasks = contentAuditTaskService.listTasksByAuditId(auditId); |
|
|
return aggregateTaskResultsAndUpdateAudit(auditId, updatedTasks); |
|
|
return aggregateTaskResultsAndUpdateAudit(auditId, updatedTasks); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* manual 审核:不调 AI,所有任务直接标记为 manual,audit 状态设为 manual_review |
|
|
* manual 人工审核:不调 AI,所有任务直接标记为 manual_review,audit 状态设为 manual_review |
|
|
*/ |
|
|
*/ |
|
|
private Map<String, Object> executeManualAudit(Long auditId) { |
|
|
private Map<String, Object> executeManualAudit(Long auditId) { |
|
|
contentAuditTaskService.lambdaUpdate() |
|
|
contentAuditTaskService.lambdaUpdate() |
|
|
.eq(MiniContentAuditTask::getContentAuditId, auditId) |
|
|
.eq(MiniContentAuditTask::getContentAuditId, auditId) |
|
|
.set(MiniContentAuditTask::getStatus, AuditConstants.TASK_TO_MANUAL) |
|
|
.set(MiniContentAuditTask::getStatus, AuditConstants.STATUS_MANUAL_REVIEW) |
|
|
.update(); |
|
|
.update(); |
|
|
contentAuditService.updateAuditStatus(auditId, AuditConstants.AUDIT_MANUAL_REVIEW, null); |
|
|
contentAuditService.updateAuditStatus(auditId, AuditConstants.STATUS_MANUAL_REVIEW); |
|
|
Map<String, Object> result = new HashMap<>(); |
|
|
Map<String, Object> result = new HashMap<>(); |
|
|
result.put("status", AuditConstants.AUDIT_MANUAL_REVIEW); |
|
|
result.put("status", AuditConstants.STATUS_MANUAL_REVIEW); |
|
|
result.put("auditId", auditId); |
|
|
result.put("auditId", auditId); |
|
|
return result; |
|
|
return result; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* mixed 审核:调 AI 仅记录 riskLevel + machineResult,不应用策略裁决,交由人工判定 |
|
|
* 按类型分组批量执行机审 |
|
|
*/ |
|
|
|
|
|
private Map<String, Object> executeMixedAudit(Long auditId) { |
|
|
|
|
|
List<MiniContentAuditTask> tasks = contentAuditTaskService.listTasksByAuditId(auditId); |
|
|
|
|
|
executeBatchMixedAuditByType(tasks); |
|
|
|
|
|
contentAuditService.updateAuditStatus(auditId, AuditConstants.AUDIT_MANUAL_REVIEW, null); |
|
|
|
|
|
Map<String, Object> result = new HashMap<>(); |
|
|
|
|
|
result.put("status", AuditConstants.AUDIT_MANUAL_REVIEW); |
|
|
|
|
|
result.put("auditId", auditId); |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 按类型分组批量执行 mixed 机审(仅记录风险信息,不裁决) |
|
|
|
|
|
*/ |
|
|
|
|
|
private void executeBatchMixedAuditByType(List<MiniContentAuditTask> tasks) { |
|
|
|
|
|
Map<String, List<MiniContentAuditTask>> grouped = tasks.stream() |
|
|
|
|
|
.collect(Collectors.groupingBy(MiniContentAuditTask::getContentType)); |
|
|
|
|
|
|
|
|
|
|
|
List<MiniContentAuditTask> textTasks = grouped.getOrDefault("text", List.of()); |
|
|
|
|
|
if (!textTasks.isEmpty()) { |
|
|
|
|
|
try { |
|
|
|
|
|
List<String> contents = textTasks.stream().map(MiniContentAuditTask::getContentValue).toList(); |
|
|
|
|
|
TextModerationPlusResponse r = aliyunContentAuditUtil.batchTextModerationPlus(contents); |
|
|
|
|
|
processBatchTextResponseForMixed(textTasks, r); |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
log.error("mixed批量文本审核失败", e); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
List<MiniContentAuditTask> imageTasks = grouped.getOrDefault("image", List.of()); |
|
|
|
|
|
if (!imageTasks.isEmpty()) { |
|
|
|
|
|
try { |
|
|
|
|
|
List<String> urls = imageTasks.stream().map(MiniContentAuditTask::getContentValue).toList(); |
|
|
|
|
|
ImageModerationResponse r = aliyunContentAuditUtil.batchImageModeration(urls); |
|
|
|
|
|
processBatchImageResponseForMixed(imageTasks, r); |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
log.error("mixed批量图片审核失败", e); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
List<MiniContentAuditTask> videoTasks = grouped.getOrDefault("video", List.of()); |
|
|
|
|
|
for (MiniContentAuditTask task : videoTasks) { |
|
|
|
|
|
try { |
|
|
|
|
|
handleVideoAudit(task, task.getContentValue()); |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
log.error("mixed视频审核失败, taskId={}", task.getId(), e); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 批量文本审核结果仅记录风险信息(mixed 模式) |
|
|
|
|
|
*/ |
|
|
|
|
|
private void processBatchTextResponseForMixed(List<MiniContentAuditTask> tasks, TextModerationPlusResponse response) { |
|
|
|
|
|
String machineResultJson = JSON.toJSONString(response); |
|
|
|
|
|
String requestId = extractRequestIdFromResponse(response); |
|
|
|
|
|
List<?> dataList = extractDataListFromResponse(response); |
|
|
|
|
|
for (int i = 0; i < tasks.size(); i++) { |
|
|
|
|
|
MiniContentAuditTask task = tasks.get(i); |
|
|
|
|
|
if (i < (dataList != null ? dataList.size() : 0)) { |
|
|
|
|
|
Object data = dataList.get(i); |
|
|
|
|
|
String riskLevel = extractRiskLevelFromDataItem(data); |
|
|
|
|
|
String label = extractLabelFromDataItem(data); |
|
|
|
|
|
Float confidence = extractConfidenceFromDataItem(data); |
|
|
|
|
|
String description = extractDescriptionFromDataItem(data); |
|
|
|
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
|
|
|
task.getId(), machineResultJson, riskLevel, null, null, |
|
|
|
|
|
label, confidence, description, requestId); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 批量图片审核结果仅记录风险信息(mixed 模式) |
|
|
|
|
|
*/ |
|
|
|
|
|
private void processBatchImageResponseForMixed(List<MiniContentAuditTask> tasks, ImageModerationResponse response) { |
|
|
|
|
|
String machineResultJson = JSON.toJSONString(response); |
|
|
|
|
|
String requestId = extractRequestIdFromResponse(response); |
|
|
|
|
|
List<?> dataList = extractDataListFromResponse(response); |
|
|
|
|
|
for (int i = 0; i < tasks.size(); i++) { |
|
|
|
|
|
MiniContentAuditTask task = tasks.get(i); |
|
|
|
|
|
if (i < (dataList != null ? dataList.size() : 0)) { |
|
|
|
|
|
Object data = dataList.get(i); |
|
|
|
|
|
String riskLevel = extractRiskLevelFromDataItem(data); |
|
|
|
|
|
String label = extractLabelFromDataItem(data); |
|
|
|
|
|
Float confidence = extractConfidenceFromDataItem(data); |
|
|
|
|
|
String description = extractDescriptionFromDataItem(data); |
|
|
|
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
|
|
|
task.getId(), machineResultJson, riskLevel, null, null, |
|
|
|
|
|
label, confidence, description, requestId); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 查找审核配置。 |
|
|
|
|
|
*/ |
|
|
|
|
|
private MiniContentAuditConfig findAuditConfig(String moduleCode) { |
|
|
|
|
|
LambdaQueryWrapper<MiniContentAuditConfig> queryWrapper = new LambdaQueryWrapper<>(); |
|
|
|
|
|
queryWrapper.eq(MiniContentAuditConfig::getModuleCode, moduleCode); |
|
|
|
|
|
queryWrapper.eq(MiniContentAuditConfig::getDeleted, false); |
|
|
|
|
|
queryWrapper.last("LIMIT 1"); |
|
|
|
|
|
return contentAuditConfigService.getOne(queryWrapper); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 判断审核是否已关闭。 |
|
|
|
|
|
* MiniContentAuditConfig.auditEnable: false=开启审核, true=关闭审核 |
|
|
|
|
|
*/ |
|
|
|
|
|
private boolean isAuditDisabled(MiniContentAuditConfig config) { |
|
|
|
|
|
Boolean auditEnable = config.getAuditEnable(); |
|
|
|
|
|
return Boolean.TRUE.equals(auditEnable); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 按类型分组批量执行机审(machine 模式:调 AI 并按策略裁决) |
|
|
|
|
|
*/ |
|
|
*/ |
|
|
private void executeBatchAuditByType(List<MiniContentAuditTask> tasks, String strictness) { |
|
|
private void executeBatchAuditByType(List<MiniContentAuditTask> tasks, String strictness) { |
|
|
Map<String, List<MiniContentAuditTask>> grouped = tasks.stream() |
|
|
Map<String, List<MiniContentAuditTask>> grouped = tasks.stream() |
|
|
@ -225,7 +108,7 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
log.error("批量文本审核失败", e); |
|
|
log.error("批量文本审核失败", e); |
|
|
for (MiniContentAuditTask task : textTasks) { |
|
|
for (MiniContentAuditTask task : textTasks) { |
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
task.getId(), null, null, null, AuditConstants.TASK_TO_MANUAL, |
|
|
task.getId(), null, null, AuditConstants.STATUS_MANUAL_REVIEW, |
|
|
null, null, null, null); |
|
|
null, null, null, null); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -233,15 +116,14 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
|
|
|
|
|
|
List<MiniContentAuditTask> imageTasks = grouped.getOrDefault("image", List.of()); |
|
|
List<MiniContentAuditTask> imageTasks = grouped.getOrDefault("image", List.of()); |
|
|
if (!imageTasks.isEmpty()) { |
|
|
if (!imageTasks.isEmpty()) { |
|
|
try { |
|
|
for (MiniContentAuditTask task : imageTasks) { |
|
|
List<String> urls = imageTasks.stream().map(MiniContentAuditTask::getContentValue).toList(); |
|
|
try { |
|
|
ImageModerationResponse r = aliyunContentAuditUtil.batchImageModeration(urls); |
|
|
ImageModerationResponse r = aliyunContentAuditUtil.imageModeration(task.getContentValue()); |
|
|
processBatchImageResponse(imageTasks, r, strictness); |
|
|
processSingleImageResponse(task, r, strictness); |
|
|
} catch (Exception e) { |
|
|
} catch (Exception e) { |
|
|
log.error("批量图片审核失败", e); |
|
|
log.error("图片审核失败, taskId={}", task.getId(), e); |
|
|
for (MiniContentAuditTask task : imageTasks) { |
|
|
|
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
task.getId(), null, null, null, AuditConstants.TASK_TO_MANUAL, |
|
|
task.getId(), null, null, AuditConstants.STATUS_MANUAL_REVIEW, |
|
|
null, null, null, null); |
|
|
null, null, null, null); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -255,29 +137,47 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 批量文本审核结果处理(machine 模式:按策略裁决) |
|
|
* 批量文本审核结果处理(machine 模式:按策略裁决) |
|
|
|
|
|
* <p> |
|
|
|
|
|
* body.data 结构:{ riskLevel: "high", result: [{ label, confidence, description }, ...] } |
|
|
*/ |
|
|
*/ |
|
|
private void processBatchTextResponse(List<MiniContentAuditTask> tasks, TextModerationPlusResponse response, String strictness) { |
|
|
private void processBatchTextResponse(List<MiniContentAuditTask> tasks, TextModerationPlusResponse response, String strictness) { |
|
|
String machineResultJson = JSON.toJSONString(response); |
|
|
String machineResultJson = JSON.toJSONString(response); |
|
|
String requestId = extractRequestIdFromResponse(response); |
|
|
String requestId = extractRequestIdFromResponse(response); |
|
|
List<?> dataList = extractDataListFromResponse(response); |
|
|
|
|
|
|
|
|
// body.data 是对象,不是数组
|
|
|
|
|
|
JSONObject dataObj = extractDataObjectFromResponse(response); |
|
|
|
|
|
if (dataObj == null) { |
|
|
|
|
|
log.info("文本审核返回data为空, requestId={}", requestId); |
|
|
|
|
|
for (MiniContentAuditTask task : tasks) { |
|
|
|
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
|
|
|
task.getId(), machineResultJson, null, AuditConstants.STATUS_MANUAL_REVIEW, |
|
|
|
|
|
null, null, null, requestId); |
|
|
|
|
|
} |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
String overallRiskLevel = dataObj.getString("riskLevel"); |
|
|
|
|
|
JSONArray resultArray = dataObj.getJSONArray("result"); |
|
|
|
|
|
log.info("文本审核结果: requestId={}, riskLevel={}, resultSize={}", |
|
|
|
|
|
requestId, overallRiskLevel, resultArray != null ? resultArray.size() : 0); |
|
|
|
|
|
|
|
|
for (int i = 0; i < tasks.size(); i++) { |
|
|
for (int i = 0; i < tasks.size(); i++) { |
|
|
MiniContentAuditTask task = tasks.get(i); |
|
|
MiniContentAuditTask task = tasks.get(i); |
|
|
if (i < (dataList != null ? dataList.size() : 0)) { |
|
|
if (resultArray != null && i < resultArray.size()) { |
|
|
Object data = dataList.get(i); |
|
|
JSONObject item = resultArray.getJSONObject(i); |
|
|
String riskLevel = extractRiskLevelFromDataItem(data); |
|
|
String label = item.getString("label"); |
|
|
String label = extractLabelFromDataItem(data); |
|
|
Integer confidence = item.getInteger("confidence"); |
|
|
Float confidence = extractConfidenceFromDataItem(data); |
|
|
String description = item.getString("description"); |
|
|
String description = extractDescriptionFromDataItem(data); |
|
|
log.info("文本审核[{}]: label={}, confidence={}, description={}", i, label, confidence, description); |
|
|
if (riskLevel == null) { |
|
|
|
|
|
|
|
|
if (overallRiskLevel == null) { |
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
task.getId(), machineResultJson, null, null, AuditConstants.TASK_TO_MANUAL, |
|
|
task.getId(), machineResultJson, null, AuditConstants.STATUS_MANUAL_REVIEW, |
|
|
label, confidence, description, requestId); |
|
|
label, confidence, description, requestId); |
|
|
} else { |
|
|
} else { |
|
|
String result = applyStrategy(riskLevel, strictness); |
|
|
String status = applyStrategy(overallRiskLevel, strictness); |
|
|
String taskStatus = AuditConstants.RESULT_PASSED.equals(result) |
|
|
|
|
|
? AuditConstants.TASK_SUCCESS : AuditConstants.TASK_TO_MANUAL; |
|
|
|
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
task.getId(), machineResultJson, riskLevel, result, taskStatus, |
|
|
task.getId(), machineResultJson, overallRiskLevel, status, |
|
|
label, confidence, description, requestId); |
|
|
label, confidence, description, requestId); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -285,33 +185,37 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 批量图片审核结果处理(machine 模式:按策略裁决) |
|
|
* 单张图片审核结果处理(machine 模式:按策略裁决) |
|
|
*/ |
|
|
*/ |
|
|
private void processBatchImageResponse(List<MiniContentAuditTask> tasks, ImageModerationResponse response, String strictness) { |
|
|
private void processSingleImageResponse(MiniContentAuditTask task, ImageModerationResponse response, String strictness) { |
|
|
String machineResultJson = JSON.toJSONString(response); |
|
|
String machineResultJson = JSON.toJSONString(response); |
|
|
String requestId = extractRequestIdFromResponse(response); |
|
|
String requestId = extractRequestIdFromResponse(response); |
|
|
List<?> dataList = extractDataListFromResponse(response); |
|
|
|
|
|
for (int i = 0; i < tasks.size(); i++) { |
|
|
JSONObject dataObj = extractDataObjectFromResponse(response); |
|
|
MiniContentAuditTask task = tasks.get(i); |
|
|
if (dataObj == null) { |
|
|
if (i < (dataList != null ? dataList.size() : 0)) { |
|
|
log.info("图片审核返回data为空, taskId={}", task.getId()); |
|
|
Object data = dataList.get(i); |
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
String riskLevel = extractRiskLevelFromDataItem(data); |
|
|
task.getId(), machineResultJson, null, AuditConstants.STATUS_MANUAL_REVIEW, |
|
|
String label = extractLabelFromDataItem(data); |
|
|
null, null, null, requestId); |
|
|
Float confidence = extractConfidenceFromDataItem(data); |
|
|
return; |
|
|
String description = extractDescriptionFromDataItem(data); |
|
|
} |
|
|
if (riskLevel == null) { |
|
|
|
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
String riskLevel = dataObj.getString("riskLevel"); |
|
|
task.getId(), machineResultJson, null, null, AuditConstants.TASK_TO_MANUAL, |
|
|
String label = dataObj.getString("label"); |
|
|
label, confidence, description, requestId); |
|
|
int confidence = dataObj.getIntValue("confidence"); |
|
|
} else { |
|
|
String description = dataObj.getString("description"); |
|
|
String result = applyStrategy(riskLevel, strictness); |
|
|
log.info("图片审核结果: taskId={}, riskLevel={}, label={}, confidence={}, description={}", |
|
|
String taskStatus = AuditConstants.RESULT_PASSED.equals(result) |
|
|
task.getId(), riskLevel, label, confidence, description); |
|
|
? AuditConstants.TASK_SUCCESS : AuditConstants.TASK_TO_MANUAL; |
|
|
|
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
if (riskLevel == null) { |
|
|
task.getId(), machineResultJson, riskLevel, result, taskStatus, |
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
label, confidence, description, requestId); |
|
|
task.getId(), machineResultJson, null, AuditConstants.STATUS_MANUAL_REVIEW, |
|
|
} |
|
|
label, confidence, description, requestId); |
|
|
} |
|
|
} else { |
|
|
|
|
|
String status = applyStrategy(riskLevel, strictness); |
|
|
|
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
|
|
|
task.getId(), machineResultJson, riskLevel, status, |
|
|
|
|
|
label, confidence, description, requestId); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -341,109 +245,62 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
return response.getBody().getData().getTaskId(); |
|
|
return response.getBody().getData().getTaskId(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** 从响应的 body 中提取 requestId */ |
|
|
/** 反射提取 body.requestId */ |
|
|
private String extractRequestIdFromResponse(Object response) { |
|
|
private String extractRequestIdFromResponse(Object response) { |
|
|
try { |
|
|
try { |
|
|
Object body = invokeGetter(response, "getBody"); |
|
|
Method getBody = response.getClass().getMethod("getBody"); |
|
|
|
|
|
Object body = getBody.invoke(response); |
|
|
if (body == null) return null; |
|
|
if (body == null) return null; |
|
|
Object requestId = invokeGetter(body, "getRequestId"); |
|
|
Method getRequestId = body.getClass().getMethod("getRequestId"); |
|
|
|
|
|
Object requestId = getRequestId.invoke(body); |
|
|
return requestId != null ? requestId.toString() : null; |
|
|
return requestId != null ? requestId.toString() : null; |
|
|
} catch (Exception e) { |
|
|
} catch (Exception e) { |
|
|
return null; |
|
|
return null; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** 从响应的 body 中提取 data 列表 */ |
|
|
/** 反射提取 body.data,转为 JSONObject */ |
|
|
private List<?> extractDataListFromResponse(Object response) { |
|
|
private JSONObject extractDataObjectFromResponse(Object response) { |
|
|
try { |
|
|
try { |
|
|
Object body = invokeGetter(response, "getBody"); |
|
|
Method getBody = response.getClass().getMethod("getBody"); |
|
|
|
|
|
Object body = getBody.invoke(response); |
|
|
if (body == null) return null; |
|
|
if (body == null) return null; |
|
|
Object data = invokeGetter(body, "getData"); |
|
|
Method getData = body.getClass().getMethod("getData"); |
|
|
if (data instanceof List<?> list) return list; |
|
|
Object data = getData.invoke(body); |
|
|
return null; |
|
|
if (data == null) return null; |
|
|
} catch (Exception e) { |
|
|
return JSON.parseObject(JSON.toJSONString(data)); |
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** 从 data 列表中单个元素提取 riskLevel */ |
|
|
|
|
|
private String extractRiskLevelFromDataItem(Object dataItem) { |
|
|
|
|
|
try { |
|
|
|
|
|
Object riskLevel = invokeGetter(dataItem, "getRiskLevel"); |
|
|
|
|
|
return riskLevel != null ? riskLevel.toString() : null; |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** 从 data 列表中单个元素提取 label */ |
|
|
|
|
|
private String extractLabelFromDataItem(Object dataItem) { |
|
|
|
|
|
try { |
|
|
|
|
|
Object label = invokeGetter(dataItem, "getLabel"); |
|
|
|
|
|
return label != null ? label.toString() : null; |
|
|
|
|
|
} catch (Exception e) { |
|
|
} catch (Exception e) { |
|
|
return null; |
|
|
return null; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** 从 data 列表中单个元素提取 confidence */ |
|
|
|
|
|
private Float extractConfidenceFromDataItem(Object dataItem) { |
|
|
|
|
|
try { |
|
|
|
|
|
Object confidence = invokeGetter(dataItem, "getConfidence"); |
|
|
|
|
|
if (confidence instanceof Number n) return n.floatValue(); |
|
|
|
|
|
return null; |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** 从 data 列表中单个元素提取 description */ |
|
|
|
|
|
private String extractDescriptionFromDataItem(Object dataItem) { |
|
|
|
|
|
try { |
|
|
|
|
|
Object description = invokeGetter(dataItem, "getDescription"); |
|
|
|
|
|
return description != null ? description.toString() : null; |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 反射调用目标对象的 getter 方法 |
|
|
|
|
|
*/ |
|
|
|
|
|
private Object invokeGetter(Object target, String methodName) throws Exception { |
|
|
|
|
|
Method method = target.getClass().getMethod(methodName); |
|
|
|
|
|
return method.invoke(target); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ================================================================
|
|
|
// ================================================================
|
|
|
// 策略映射
|
|
|
// 策略映射
|
|
|
// ================================================================
|
|
|
// ================================================================
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* TODO 根据 strictness 策略,将 riskLevel 映射为任务 result。 |
|
|
* 根据 riskLevel + strictness,返回 task status。 |
|
|
* <pre> |
|
|
* <pre> |
|
|
* auto: NONE→passed, MEDIUM→failed, HIGH→failed |
|
|
* auto: NONE→passed, MEDIUM→rejected, HIGH→rejected |
|
|
* normal: NONE→passed, MEDIUM→manual, HIGH→failed |
|
|
* normal: NONE→passed, MEDIUM→manual_review, HIGH→rejected |
|
|
* cautious: NONE→passed, MEDIUM→manual, HIGH→manual |
|
|
* cautious: NONE→passed, MEDIUM→manual_review, HIGH→manual_review |
|
|
* </pre> |
|
|
* </pre> |
|
|
*/ |
|
|
*/ |
|
|
private String applyStrategy(String riskLevel, String strictness) { |
|
|
private String applyStrategy(String riskLevel, String strictness) { |
|
|
if (AuditConstants.RISK_NONE.equals(riskLevel)) { |
|
|
if (AuditConstants.RISK_NONE.equals(riskLevel)) { |
|
|
return AuditConstants.RESULT_PASSED; |
|
|
return AuditConstants.STATUS_PASSED; |
|
|
} |
|
|
} |
|
|
if (AuditConstants.STRATEGY_CAUTIOUS.equals(strictness)) { |
|
|
if (AuditConstants.STRATEGY_CAUTIOUS.equals(strictness)) { |
|
|
// cautious: 非 NONE 只更新审核状态 → 一律转人工
|
|
|
return AuditConstants.STATUS_MANUAL_REVIEW; |
|
|
return null; |
|
|
|
|
|
} |
|
|
} |
|
|
if (AuditConstants.STRATEGY_AUTO.equals(strictness)) { |
|
|
if (AuditConstants.STRATEGY_AUTO.equals(strictness)) { |
|
|
// auto: 非 NONE 一律不通过
|
|
|
return AuditConstants.STATUS_REJECTED; |
|
|
return AuditConstants.RESULT_FAILED; |
|
|
|
|
|
} |
|
|
} |
|
|
// normal(默认):MEDIUM→ 审核状态转人工,HIGH→不通过
|
|
|
// normal(默认):MEDIUM→manual_review, HIGH→rejected
|
|
|
if (AuditConstants.RISK_MEDIUM.equals(riskLevel)) { |
|
|
if (AuditConstants.RISK_MEDIUM.equals(riskLevel)) { |
|
|
return null; |
|
|
return AuditConstants.STATUS_MANUAL_REVIEW; |
|
|
} |
|
|
} |
|
|
return AuditConstants.RESULT_FAILED; |
|
|
return AuditConstants.STATUS_REJECTED; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// ================================================================
|
|
|
// ================================================================
|
|
|
@ -451,74 +308,58 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
// ================================================================
|
|
|
// ================================================================
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 汇总所有任务结果,更新 audit 最终状态。 |
|
|
* 汇总所有任务状态,更新 audit。 |
|
|
* <p> |
|
|
* <p> |
|
|
* 汇总规则: |
|
|
* 汇总规则: |
|
|
* - 任一 task.result = failed → audit.status = failed |
|
|
* - 任一 task.status = rejected → audit.status = rejected |
|
|
* - 有 task.result = to_manual → audit.status = manual_review |
|
|
* - 有 task.status = manual_review → audit.status = manual_review |
|
|
* - 全部 task.result = passed → audit.status = passed |
|
|
* - 全部 task.status = passed → audit.status = passed |
|
|
* - 视频任务未完成(result 为 null)→ 保持 reviewing |
|
|
* - 视频任务未完成(status = reviewing)→ 保持 reviewing |
|
|
* </pre> |
|
|
|
|
|
* <p> |
|
|
|
|
|
* MiniContentAudit 字段含义: |
|
|
|
|
|
* - status: reviewing(机审中) / passed(通过) / failed(不通过) / manual_review(待人工) / appealing(申诉中) |
|
|
|
|
|
* - final_result: passed / failed(仅终态;manual_review 时留空,等待人工判定) |
|
|
|
|
|
*/ |
|
|
*/ |
|
|
private Map<String, Object> aggregateTaskResultsAndUpdateAudit(Long auditId, List<MiniContentAuditTask> tasks) { |
|
|
private Map<String, Object> aggregateTaskResultsAndUpdateAudit(Long auditId, List<MiniContentAuditTask> tasks) { |
|
|
boolean hasFailedTask = false; |
|
|
boolean hasRejected = false; |
|
|
boolean hasManualTask = false; |
|
|
boolean hasManualReview = false; |
|
|
boolean allTasksPassed = true; |
|
|
boolean allPassed = true; |
|
|
|
|
|
|
|
|
for (MiniContentAuditTask task : tasks) { |
|
|
for (MiniContentAuditTask task : tasks) { |
|
|
String taskResult = task.getResult(); |
|
|
String taskStatus = task.getStatus(); |
|
|
|
|
|
|
|
|
if (AuditConstants.RESULT_FAILED.equals(taskResult)) { |
|
|
if (AuditConstants.STATUS_REJECTED.equals(taskStatus)) { |
|
|
hasFailedTask = true; |
|
|
hasRejected = true; |
|
|
allTasksPassed = false; |
|
|
allPassed = false; |
|
|
break; // 已有 failed,无需继续遍历
|
|
|
break; |
|
|
} |
|
|
} |
|
|
if (AuditConstants.TASK_TO_MANUAL.equals(task.getStatus())) { |
|
|
if (AuditConstants.STATUS_MANUAL_REVIEW.equals(taskStatus)) { |
|
|
hasManualTask = true; |
|
|
hasManualReview = true; |
|
|
allTasksPassed = false; |
|
|
allPassed = false; |
|
|
} else if (!AuditConstants.RESULT_PASSED.equals(taskResult)) { |
|
|
} else if (!AuditConstants.STATUS_PASSED.equals(taskStatus)) { |
|
|
// result 为 null 或其他未知值 → 未完成
|
|
|
allPassed = false; |
|
|
allTasksPassed = false; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 视频任务 result 为 null 时, 不能算通过
|
|
|
// 视频任务未完成时不能算通过
|
|
|
for (MiniContentAuditTask task : tasks) { |
|
|
for (MiniContentAuditTask task : tasks) { |
|
|
if ("video".equals(task.getContentType()) && task.getResult() == null) { |
|
|
if ("video".equals(task.getContentType()) && AuditConstants.STATUS_REVIEWING.equals(task.getStatus())) { |
|
|
allTasksPassed = false; |
|
|
allPassed = false; |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 根据汇总结果确定 audit 状态
|
|
|
|
|
|
String auditStatus; |
|
|
String auditStatus; |
|
|
String finalResultValue; |
|
|
if (hasRejected) { |
|
|
|
|
|
auditStatus = AuditConstants.STATUS_REJECTED; |
|
|
if (hasFailedTask) { |
|
|
} else if (hasManualReview) { |
|
|
auditStatus = AuditConstants.AUDIT_FAILED; |
|
|
auditStatus = AuditConstants.STATUS_MANUAL_REVIEW; |
|
|
finalResultValue = "failed"; |
|
|
} else if (allPassed && !tasks.isEmpty()) { |
|
|
} else if (hasManualTask) { |
|
|
auditStatus = AuditConstants.STATUS_PASSED; |
|
|
auditStatus = AuditConstants.AUDIT_MANUAL_REVIEW; |
|
|
|
|
|
finalResultValue = null; // 转人工不是终态,final_result 留空等待人工判定
|
|
|
|
|
|
} else if (allTasksPassed && !tasks.isEmpty()) { |
|
|
|
|
|
auditStatus = AuditConstants.AUDIT_PASSED; |
|
|
|
|
|
finalResultValue = "passed"; |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
// 有任务未完成(如视频异步等待中)
|
|
|
auditStatus = AuditConstants.STATUS_REVIEWING; |
|
|
auditStatus = AuditConstants.AUDIT_REVIEWING; |
|
|
|
|
|
finalResultValue = null; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 非 reviewing 状态下更新 audit(manual_review 虽无 finalResult 也要更新 status)
|
|
|
if (!AuditConstants.STATUS_REVIEWING.equals(auditStatus)) { |
|
|
if (!AuditConstants.AUDIT_REVIEWING.equals(auditStatus)) { |
|
|
contentAuditService.updateAuditStatus(auditId, auditStatus); |
|
|
contentAuditService.updateAuditStatus(auditId, auditStatus, finalResultValue); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 返回给业务层的审核结果
|
|
|
|
|
|
Map<String, Object> resultMap = new HashMap<>(); |
|
|
Map<String, Object> resultMap = new HashMap<>(); |
|
|
resultMap.put("status", auditStatus); |
|
|
resultMap.put("status", auditStatus); |
|
|
resultMap.put("auditId", auditId); |
|
|
resultMap.put("auditId", auditId); |
|
|
@ -529,12 +370,6 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
// 视频异步审核结果轮询
|
|
|
// 视频异步审核结果轮询
|
|
|
// ================================================================
|
|
|
// ================================================================
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 轮询所有待处理的视频审核异步结果,更新任务和汇总状态。 |
|
|
|
|
|
* 供定时任务 {@code VideoAuditPollJob} 调用。 |
|
|
|
|
|
* |
|
|
|
|
|
* @return 本次成功处理的视频任务数量 |
|
|
|
|
|
*/ |
|
|
|
|
|
@Override |
|
|
@Override |
|
|
public int pollVideoAuditResults() { |
|
|
public int pollVideoAuditResults() { |
|
|
List<MiniContentAuditTask> pendingTasks = contentAuditTaskService.getPendingVideoTasks(); |
|
|
List<MiniContentAuditTask> pendingTasks = contentAuditTaskService.getPendingVideoTasks(); |
|
|
@ -557,7 +392,7 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 仅 machine 类型需要重新汇总,mixed 的 audit 已为 manual_review 不参与汇总
|
|
|
// machine 类型需要重新汇总
|
|
|
for (Long auditId : affectedAuditIds) { |
|
|
for (Long auditId : affectedAuditIds) { |
|
|
try { |
|
|
try { |
|
|
MiniContentAudit audit = contentAuditService.getById(auditId); |
|
|
MiniContentAudit audit = contentAuditService.getById(auditId); |
|
|
@ -574,9 +409,6 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
return processedCount; |
|
|
return processedCount; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 处理单条视频审核任务的异步结果。返回 true 表示结果已回填完成。 |
|
|
|
|
|
*/ |
|
|
|
|
|
private boolean processSingleVideoTask(MiniContentAuditTask task) { |
|
|
private boolean processSingleVideoTask(MiniContentAuditTask task) { |
|
|
String asyncTaskId = task.getTaskId(); |
|
|
String asyncTaskId = task.getTaskId(); |
|
|
VideoModerationResultResponse response = aliyunContentAuditUtil.videoModerationResult(asyncTaskId); |
|
|
VideoModerationResultResponse response = aliyunContentAuditUtil.videoModerationResult(asyncTaskId); |
|
|
@ -604,54 +436,35 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 从阿里云响应中直接提取 riskLevel(none/medium/high)
|
|
|
|
|
|
String riskLevel = extractVideoRiskLevel(dataJson); |
|
|
String riskLevel = extractVideoRiskLevel(dataJson); |
|
|
if (riskLevel == null) { |
|
|
if (riskLevel == null) { |
|
|
log.warn("视频审核结果中未找到riskLevel, taskId={}", task.getId()); |
|
|
log.warn("视频审核结果中未找到riskLevel, taskId={}", task.getId()); |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 查找关联的审核记录
|
|
|
|
|
|
MiniContentAudit audit = contentAuditService.getById(task.getContentAuditId()); |
|
|
MiniContentAudit audit = contentAuditService.getById(task.getContentAuditId()); |
|
|
if (audit == null) { |
|
|
if (audit == null) { |
|
|
log.warn("未找到关联审核记录, taskId={}", task.getId()); |
|
|
log.warn("未找到关联审核记录, taskId={}", task.getId()); |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// mixed 类型:记录机审结果,更新审核状态 manual,不裁决
|
|
|
// 查找配置获取策略
|
|
|
if (AuditConstants.AUDIT_TYPE_MIXED.equals(audit.getAuditType())) { |
|
|
|
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
|
|
|
task.getId(), dataJson, riskLevel, null, "manual", |
|
|
|
|
|
null, null, null, null); |
|
|
|
|
|
log.info("视频任务AI分析完成(mixed), taskId={}, riskLevel={}", task.getId(), riskLevel); |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// machine 类型:按策略裁决
|
|
|
|
|
|
String strictness = AuditConstants.STRATEGY_NORMAL; |
|
|
String strictness = AuditConstants.STRATEGY_NORMAL; |
|
|
MiniContentAuditConfig config = findAuditConfig(audit.getModuleCode()); |
|
|
MiniContentAuditConfig config = findAuditConfig(audit.getModuleCode()); |
|
|
if (config != null && config.getRiskStrategy() != null) { |
|
|
if (config != null && config.getRiskStrategy() != null) { |
|
|
strictness = config.getRiskStrategy(); |
|
|
strictness = config.getRiskStrategy(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
String result = applyStrategy(riskLevel, strictness); |
|
|
String status = applyStrategy(riskLevel, strictness); |
|
|
String taskStatus = AuditConstants.RESULT_PASSED.equals(result) |
|
|
|
|
|
? AuditConstants.TASK_SUCCESS : AuditConstants.TASK_TO_MANUAL; |
|
|
|
|
|
|
|
|
|
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
contentAuditTaskService.updateTaskMachineResult( |
|
|
task.getId(), dataJson, riskLevel, result, taskStatus, |
|
|
task.getId(), dataJson, riskLevel, status, |
|
|
null, null, null, null); |
|
|
null, null, null, null); |
|
|
|
|
|
|
|
|
log.info("视频任务审核完成, taskId={}, riskLevel={}, strictness={}, result={}", |
|
|
log.info("视频任务审核完成, taskId={}, riskLevel={}, strictness={}, status={}", |
|
|
task.getId(), riskLevel, strictness, result); |
|
|
task.getId(), riskLevel, strictness, status); |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 判断视频异步审核是否已完成。 |
|
|
|
|
|
* 阿里云视频审核完成后 data 中会出现 RiskLevel 字段(none/medium/high), |
|
|
|
|
|
* 未完成时该字段不存在。 |
|
|
|
|
|
*/ |
|
|
|
|
|
private boolean isVideoAuditCompleted(String dataJson) { |
|
|
private boolean isVideoAuditCompleted(String dataJson) { |
|
|
try { |
|
|
try { |
|
|
JSONObject json = JSON.parseObject(dataJson); |
|
|
JSONObject json = JSON.parseObject(dataJson); |
|
|
@ -662,10 +475,6 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 从视频审核结果JSON中直接提取 riskLevel(none/medium/high)。 |
|
|
|
|
|
* 阿里云视频审核完成后 data 中包含小写 riskLevel 字段。 |
|
|
|
|
|
*/ |
|
|
|
|
|
private String extractVideoRiskLevel(String dataJson) { |
|
|
private String extractVideoRiskLevel(String dataJson) { |
|
|
try { |
|
|
try { |
|
|
JSONObject json = JSON.parseObject(dataJson); |
|
|
JSONObject json = JSON.parseObject(dataJson); |
|
|
@ -675,4 +484,23 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
return null; |
|
|
return null; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 查找审核配置。 |
|
|
|
|
|
*/ |
|
|
|
|
|
private MiniContentAuditConfig findAuditConfig(String moduleCode) { |
|
|
|
|
|
LambdaQueryWrapper<MiniContentAuditConfig> queryWrapper = new LambdaQueryWrapper<>(); |
|
|
|
|
|
queryWrapper.eq(MiniContentAuditConfig::getModuleCode, moduleCode); |
|
|
|
|
|
queryWrapper.eq(MiniContentAuditConfig::getDeleted, false); |
|
|
|
|
|
queryWrapper.last("LIMIT 1"); |
|
|
|
|
|
return contentAuditConfigService.getOne(queryWrapper); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 判断审核是否已关闭。 |
|
|
|
|
|
*/ |
|
|
|
|
|
private boolean isAuditDisabled(MiniContentAuditConfig config) { |
|
|
|
|
|
Boolean auditEnable = config.getAuditEnable(); |
|
|
|
|
|
return Boolean.TRUE.equals(auditEnable); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|