|
|
@ -16,8 +16,9 @@ import com.youlai.boot.common.util.AliyunContentAuditUtil; |
|
|
import lombok.RequiredArgsConstructor; |
|
|
import lombok.RequiredArgsConstructor; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import org.springframework.stereotype.Service; |
|
|
import org.springframework.stereotype.Service; |
|
|
import org.springframework.transaction.annotation.Propagation; |
|
|
import org.springframework.transaction.PlatformTransactionManager; |
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
import org.springframework.transaction.TransactionDefinition; |
|
|
|
|
|
import org.springframework.transaction.support.TransactionTemplate; |
|
|
|
|
|
|
|
|
import java.lang.reflect.Method; |
|
|
import java.lang.reflect.Method; |
|
|
import java.util.*; |
|
|
import java.util.*; |
|
|
@ -38,6 +39,7 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
private final ContentAuditService contentAuditService; |
|
|
private final ContentAuditService contentAuditService; |
|
|
private final ContentAuditTaskService contentAuditTaskService; |
|
|
private final ContentAuditTaskService contentAuditTaskService; |
|
|
private final AliyunContentAuditUtil aliyunContentAuditUtil; |
|
|
private final AliyunContentAuditUtil aliyunContentAuditUtil; |
|
|
|
|
|
private final PlatformTransactionManager transactionManager; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 执行内容审核(供业务层在内容创建/修改后调用)。 |
|
|
* 执行内容审核(供业务层在内容创建/修改后调用)。 |
|
|
@ -48,8 +50,32 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
* @return {status, auditId};配置关闭或无配置时返回 null |
|
|
* @return {status, auditId};配置关闭或无配置时返回 null |
|
|
*/ |
|
|
*/ |
|
|
@Override |
|
|
@Override |
|
|
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) |
|
|
|
|
|
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) 审核核心逻辑在独立事务中运行,异常不影响业务主事务
|
|
|
|
|
|
TransactionTemplate txTemplate = new TransactionTemplate(transactionManager); |
|
|
|
|
|
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); |
|
|
|
|
|
Map<String, Object> result = txTemplate.execute(status -> doExecuteAudit(moduleCode, bizId, content, triggerType)); |
|
|
|
|
|
|
|
|
|
|
|
// 2) 业务回调在当前事务中执行,避免跨事务锁冲突
|
|
|
|
|
|
if (result != null && result.get("auditId") != null) { |
|
|
|
|
|
String auditStatus = (String) result.get("status"); |
|
|
|
|
|
if (!AuditConstants.STATUS_REVIEWING.equals(auditStatus)) { |
|
|
|
|
|
try { |
|
|
|
|
|
contentAuditService.executeCallback((Long) result.get("auditId")); |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
log.error("业务回调失败, auditId={}, status={}", result.get("auditId"), auditStatus, e); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 审核核心逻辑(在独立事务中运行)。 |
|
|
|
|
|
* 包含:查配置 → 创建审核记录 → 创建任务 → 调用阿里云机审 → 汇总结果 → 更新审核状态 |
|
|
|
|
|
*/ |
|
|
|
|
|
private Map<String, Object> doExecuteAudit(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)) { |
|
|
@ -68,7 +94,6 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
|
|
|
|
|
|
// 4) 按审核类型执行
|
|
|
// 4) 按审核类型执行
|
|
|
if (AuditConstants.AUDIT_TYPE_MANUAL.equals(auditType)) { |
|
|
if (AuditConstants.AUDIT_TYPE_MANUAL.equals(auditType)) { |
|
|
// 人工审核
|
|
|
|
|
|
return executeManualAudit(auditId); |
|
|
return executeManualAudit(auditId); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -501,13 +526,24 @@ public class AuditExecutorServiceImpl implements AuditExecutorService { |
|
|
MiniContentAudit audit = contentAuditService.getById(auditId); |
|
|
MiniContentAudit audit = contentAuditService.getById(auditId); |
|
|
if (audit != null && AuditConstants.AUDIT_TYPE_MACHINE.equals(audit.getAuditType())) { |
|
|
if (audit != null && AuditConstants.AUDIT_TYPE_MACHINE.equals(audit.getAuditType())) { |
|
|
List<MiniContentAuditTask> tasks = contentAuditTaskService.listTasksByAuditId(auditId); |
|
|
List<MiniContentAuditTask> tasks = contentAuditTaskService.listTasksByAuditId(auditId); |
|
|
aggregateTaskResultsAndUpdateAudit(auditId, tasks); |
|
|
Map<String, Object> result = aggregateTaskResultsAndUpdateAudit(auditId, tasks); |
|
|
|
|
|
if (result != null) { |
|
|
|
|
|
String status = (String) result.get("status"); |
|
|
|
|
|
if (!AuditConstants.STATUS_REVIEWING.equals(status)) { |
|
|
|
|
|
contentAuditService.executeCallback(auditId); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} catch (Exception e) { |
|
|
} catch (Exception e) { |
|
|
log.error("重新汇总审核失败, auditId={}", auditId, e); |
|
|
log.error("重新汇总审核失败, auditId={}", auditId, e); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int retried = contentAuditService.retryPendingCallbacks(); |
|
|
|
|
|
if (retried > 0) { |
|
|
|
|
|
log.info("重试pending业务回调完成, 成功={}", retried); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
log.info("异步审核轮询完成, 已处理={}, 受影响审核={}", processedCount, affectedAuditIds.size()); |
|
|
log.info("异步审核轮询完成, 已处理={}, 受影响审核={}", processedCount, affectedAuditIds.size()); |
|
|
return processedCount; |
|
|
return processedCount; |
|
|
} |
|
|
} |
|
|
|