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 executeWithFailover(AliyunRequestExecutor 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 execute(Client client) throws Exception; } }