You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
6.5 KiB

package com.youlai.boot.common.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.green20220302.Client;
import com.aliyun.green20220302.models.*;
import com.aliyun.teaopenapi.models.Config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 阿里云内容安全统一审核工具类v2.0
* ----------------------------------------
* 支持
* 1. 文本审核
* 2. 图片审核
* 3. 视频审核异步
* 4. 取消视频审核任务直播流
*
* 特性
* - 自动切换备用节点cn-beijing
* - application.yml 中读取配置
* - 返回 null 表示请求失败业务层自行判断
*/
@Slf4j
@Component
public class AliyunContentAuditUtil {
@Value("${audit.aliyun.green.accessKeyId}")
private String accessKeyId;
@Value("${audit.aliyun.green.accessKeySecret}")
private String accessKeySecret;
// 主节点(上海)
private static final String REGION_PRIMARY = "cn-shanghai";
private static final String ENDPOINT_PRIMARY = "green-cip.cn-shanghai.aliyuncs.com";
// 备用节点(北京)
private static final String REGION_BACKUP = "cn-beijing";
private static final String ENDPOINT_BACKUP = "green-cip.cn-beijing.aliyuncs.com";
/**
* 构建客户端
*/
private Client createClient(boolean useBackup) throws Exception {
String region = useBackup ? REGION_BACKUP : REGION_PRIMARY;
String endpoint = useBackup ? ENDPOINT_BACKUP : ENDPOINT_PRIMARY;
Config config = new Config()
.setAccessKeyId(accessKeyId)
.setAccessKeySecret(accessKeySecret)
.setRegionId(region)
.setEndpoint(endpoint)
.setReadTimeout(6000)
.setConnectTimeout(3000);
return new Client(config);
}
/**
* 自动调用机制
* - 优先使用上海节点
* - 如果响应码为 500 或出现异常自动切换至北京节点重试一次
*/
private <T> T executeWithFailover(AliyunRequestExecutor<T> executor) {
try {
Client primary = createClient(false);
T result = executor.execute(primary);
if (isServerError(result)) {
log.warn("阿里云内容安全服务端异常,切换到北京节点重试...");
Client backup = createClient(true);
return executor.execute(backup);
}
return result;
} catch (Exception e) {
log.error("阿里云内容安全调用异常(主节点失败),切换至备用节点", e);
try {
Client backup = createClient(true);
return executor.execute(backup);
} catch (Exception ex) {
log.error("备用节点调用也失败", ex);
return null;
}
}
}
/**
* 判断是否服务端异常statusCode=500
*/
private boolean isServerError(Object response) {
try {
Integer code = (Integer) response.getClass().getMethod("getStatusCode").invoke(response);
return code != null && code == 500;
} catch (Exception ignored) {
return false;
}
}
// ===================== 文本审核 =====================
public TextModerationResponse textModeration(String content) {
return executeWithFailover(client -> {
JSONObject params = new JSONObject();
params.put("content", content);
TextModerationRequest request = new TextModerationRequest()
.setService("commentDetection")
.setServiceParameters(params.toJSONString());
return client.textModeration(request);
});
}
// ===================== 图片审核 =====================
public ImageModerationResponse imageModeration(String imageUrl) {
return executeWithFailover(client -> {
JSONObject params = new JSONObject();
JSONArray arr = new JSONArray();
arr.add(imageUrl);
params.put("images", arr);
ImageModerationRequest request = new ImageModerationRequest()
.setService("imageDetection")
.setServiceParameters(params.toJSONString());
return client.imageModeration(request);
});
}
// ===================== 视频审核(异步) =====================
public VideoModerationResponse videoModeration(String videoUrl) {
return executeWithFailover(client -> {
JSONObject params = new JSONObject();
params.put("url", videoUrl);
VideoModerationRequest request = new VideoModerationRequest()
.setService("videoDetection")
.setServiceParameters(params.toJSONString());
return client.videoModeration(request);
});
}
// ===================== 查询视频审核结果 =====================
public VideoModerationResultResponse videoModerationResult(String taskId) {
return executeWithFailover(client -> {
JSONObject params = new JSONObject();
params.put("taskId", taskId);
VideoModerationResultRequest request = new VideoModerationResultRequest()
.setService("videoDetection")
.setServiceParameters(params.toJSONString());
return client.videoModerationResult(request);
});
}
// ===================== 取消视频任务(直播流) =====================
public VideoModerationCancelResponse cancelVideoTask(String taskId) {
return executeWithFailover(client -> {
JSONObject params = new JSONObject();
params.put("taskId", taskId);
VideoModerationCancelRequest request = new VideoModerationCancelRequest()
.setService("liveStreamDetection")
.setServiceParameters(params.toJSONString());
return client.videoModerationCancel(request);
});
}
/**
* 输出调试日志
*/
public static void print(Object result) {
System.out.println(JSON.toJSONString(result, true));
}
/**
* 函数式接口用于统一封装 SDK 调用逻辑
*/
@FunctionalInterface
private interface AliyunRequestExecutor<T> {
T execute(Client client) throws Exception;
}
}